ENTAXY-248 release 1.8.1

This commit is contained in:
2022-02-28 15:20:38 +03:00
parent 4d274c4fcc
commit c826adf1db
1958 changed files with 195926 additions and 10280 deletions

View File

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

View File

@ -0,0 +1,134 @@
<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</groupId>
<artifactId>core</artifactId>
<version>1.8.1</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>artifact-management</artifactId>
<packaging>bundle</packaging>
<name>ENTAXY :: PLATFORM :: CORE :: ARTIFACT MANAGEMENT</name>
<description>ENTAXY :: PLATFORM :: CORE :: ARTIFACT MANAGEMENT</description>
<properties>
<bundle.osgi.export.pkg>
ru.entaxy.platform.core.artifact*,
ru.entaxy.platform.core.artifact.*
</bundle.osgi.export.pkg>
<bundle.osgi.private.pkg>
ru.entaxy.platform.core.artifact.impl,
ru.entaxy.platform.core.artifact.installer.builder.impl,
ru.entaxy.platform.core.artifact.installer.impl,
ru.entaxy.platform.core.artifact.repository.impl,
ru.entaxy.platform.core.artifact.repository.impl.remote,
ru.entaxy.platform.core.artifact.service.impl
</bundle.osgi.private.pkg>
<httpmime.version>4.4.1</httpmime.version>
<bundle.osgi.dynamicimport.pkg>*</bundle.osgi.dynamicimport.pkg>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Entaxy-Initializer-Class>ru.entaxy.platform.core.artifact.repository.ArtifactRepositoryInitializer?id=repositories&amp;repeat=true&amp;retries=10&amp;interval=15000</Entaxy-Initializer-Class>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>src/main/non-packaged-resources/etc/ru.entaxy.esb.artifact.repositories.cfg</file>
<type>cfg</type>
<classifier>ru.entaxy.esb.artifact.repositories</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>
ru.entaxy.esb.platform.runtime.core.initializer
</groupId>
<artifactId>init-manager</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.karaf.config</groupId>
<artifactId>org.apache.karaf.config.core</artifactId>
<version>${karaf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.karaf.cave.repository</groupId>
<artifactId>org.apache.karaf.cave.repository.api</artifactId>
<version>${cave.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>${httpmime.version}</version>
</dependency>
<dependency>
<groupId>
ru.entaxy.esb.platform.runtime.base.connecting.generator
</groupId>
<artifactId>generator-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>
ru.entaxy.esb.platform.runtime.base
</groupId>
<artifactId>base-support</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.karaf.bundle</groupId>
<artifactId>org.apache.karaf.bundle.core</artifactId>
<version>${karaf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.karaf.cellar</groupId>
<artifactId>org.apache.karaf.cellar.bundle</artifactId>
<version>${cellar.version}-ENTAXY</version>
</dependency>
<dependency>
<groupId>org.apache.karaf.cellar</groupId>
<artifactId>org.apache.karaf.cellar.core</artifactId>
<version>${cellar.version}</version>
</dependency>
<dependency>
<groupId>ru.entaxy.esb.system.commons</groupId>
<artifactId>system-commons</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,61 @@
/*-
* ~~~~~~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;
import java.io.File;
import java.util.Map;
public interface Artifact {
public static final String ARTIFACT_CATEGORY_UNKNOWN = "unknown";
public static final String ARTIFACT_CATEGORY_BLUEPRINT = "blueprint";
public static final String ARTIFACT_CATEGORY_BUNDLE = "bundle";
public static final String ARTIFACT_CATEGORY_JAR = "jar";
public static final String ARTIFACT_CATEGORY_CONFIG = "config";
public static final String ARTIFACT_CATEGORY_FEATURES = "features";
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();
public Object getContent();
// TODO add 'throws' declaration if needed
public void setContent(Object content);
public void toFile(File destination);
public byte[] asByteArray();
public Map<String, Object> getProperties();
// capabilities support
public CapabilityDescriptor provideCapability(String namespace);
public CapabilityDescriptor requireCapability(String namespace);
}

View File

@ -0,0 +1,170 @@
/*-
* ~~~~~~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;
import java.util.Calendar;
import org.apache.camel.tooling.model.Strings;
import ru.entaxy.platform.base.support.CommonUtils;
public class ArtifactCoordinates {
public static final ArtifactCoordinates EMPTY = new ArtifactCoordinates();
protected String groupId;
protected String artifactId;
protected String version = "1.0";
protected String type;
protected String classifier;
protected String versionQualifier = "";
public ArtifactCoordinates groupId(String groupId) {
setGroupId(groupId);
return this;
}
public ArtifactCoordinates artifactId(String artifactId) {
setArtifactId(artifactId);
return this;
}
public ArtifactCoordinates version(String version) {
this.versionQualifier = "";
setVersion(version);
return this;
}
public ArtifactCoordinates timestampedVersion(String version) {
version(version);
this.versionQualifier = "-" + Calendar.getInstance().getTimeInMillis();
return this;
}
public ArtifactCoordinates timestamped() {
return qualifier(Calendar.getInstance().getTimeInMillis()+"");
}
public ArtifactCoordinates timestamped(String timestamp) {
if (CommonUtils.isValid(timestamp))
return qualifier(timestamp);
else
return timestamped();
}
public ArtifactCoordinates type(String type) {
setType(type);
return this;
}
public ArtifactCoordinates qualifier(String qualifier) {
if (CommonUtils.isValid(qualifier))
this.versionQualifier = "-" + qualifier;
else
this.versionQualifier = "";
return this;
}
public ArtifactCoordinates classifier(String classifier) {
setClassifier(classifier);
return this;
}
public ArtifactCoordinates set(ArtifactCoordinates newCoordinates) {
groupId(newCoordinates.getGroupId())
.artifactId(newCoordinates.getArtifactId())
.version(newCoordinates.getVersion())
.type(newCoordinates.getType())
.classifier(newCoordinates.getClassifier());
return this;
}
public ArtifactCoordinates update(ArtifactCoordinates newCoordinates) {
if (null != newCoordinates.getGroupId())
groupId(newCoordinates.getGroupId());
if (null != newCoordinates.getArtifactId())
artifactId(newCoordinates.getArtifactId());
if (null != newCoordinates.getVersion())
version(newCoordinates.getVersion());
if (null != newCoordinates.getType())
type(newCoordinates.getType());
if (null != newCoordinates.getClassifier())
classifier(newCoordinates.getClassifier());
return this;
}
public boolean isSnapshot() {
return !Strings.isNullOrEmpty(this.version)
&& this.version.endsWith("-SNAPSHOT");
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getArtifactId() {
return artifactId;
}
public void setArtifactId(String artifactId) {
this.artifactId = artifactId;
}
public String getVersion() {
return version + versionQualifier;
}
public void setVersion(String version) {
if (!CommonUtils.isValid(version))
this.version = "1.0.0";
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;
}
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getClassifier() {
return classifier;
}
public void setClassifier(String classifier) {
this.classifier = classifier;
}
@Override
public String toString() {
String result = String.format("%s/%s/%s%s", groupId, artifactId, version, versionQualifier);
if (!Strings.isNullOrEmpty(type)) {
result += "/" + type;
if (!Strings.isNullOrEmpty(classifier))
result += "/" + classifier;
}
return result;
}
}

View File

@ -0,0 +1,83 @@
/*-
* ~~~~~~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;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
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.core.artifact.annotation.ArtifactSupport;
public class Artifacts {
private static final Logger log = LoggerFactory.getLogger(Artifacts.class);
protected static final Map<String, Class<?>> supportClasses = new HashMap<>();
static {
Artifacts.registerSupport(Blueprint.class);
}
public static final void registerSupport(Class<?> supportClass) {
if (supportClass.isAnnotationPresent(ArtifactSupport.class)) {
String artifactType = supportClass.getAnnotation(ArtifactSupport.class).supportedCategory();
Artifacts.supportClasses.put(artifactType, supportClass);
}
}
public static final DefaultArtifact create(String category) {
if (supportClasses.containsKey(category)) {
Class<?> supportClass = supportClasses.get(category);
try {
Constructor<?> c = supportClass.getConstructor();
Object instance = c.newInstance();
if (DefaultArtifact.class.isAssignableFrom(instance.getClass()))
return (DefaultArtifact)instance;
} catch (NoSuchMethodException e) {
log.error("Erorr creating artifact", e);
} catch (SecurityException e) {
log.error("Erorr creating artifact", e);
} catch (InstantiationException e) {
log.error("Erorr creating artifact", e);
} catch (IllegalAccessException e) {
log.error("Erorr creating artifact", e);
} catch (IllegalArgumentException e) {
log.error("Erorr creating artifact", e);
} catch (InvocationTargetException e) {
log.error("Erorr creating artifact", e);
}
}
return new DefaultArtifact();
}
public static final DefaultArtifact fromGenerated(Generated generated) {
DefaultArtifact result = Artifacts.create(generated.getType());
if (result != null)
result.setContent(generated.getObject());
return result;
}
}

View File

@ -0,0 +1,184 @@
/*-
* ~~~~~~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;
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;
@ArtifactSupport(supportedCategory = Artifact.ARTIFACT_CATEGORY_BLUEPRINT
, supportedContentClasses = {String.class, Document.class, byte[].class}
, defaultArtifactClassifier = Artifact.ARTIFACT_CATEGORY_BLUEPRINT
, defaultArtifactType = "xml")
public class Blueprint extends DefaultArtifact {
private final static Logger log = LoggerFactory.getLogger(Blueprint.class);
@Override
public void setContent(Object content) {
super.setContent(content);
if (this.content.getClass().equals(byte[].class)) {
String s = new String((byte[])this.content, StandardCharsets.UTF_8);
this.content = s;
}
if (this.content.getClass().equals(String.class)) {
try {
Document d = CommonXMLUtils.parseString(false, (String)this.content);
this.content = d;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void toFile(File destination) {
if (this.content instanceof String)
super.toFile(destination);
else if (this.content instanceof Document) {
Document doc = (Document)this.content;
try {
prepareManifest(doc);
CommonXMLUtils.saveDocument(doc, destination);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else if (this.content instanceof byte[]) {
// TODO to be implemented
}
}
@Override
public byte[] asByteArray() {
if (this.content instanceof byte[])
return (byte[])this.content;
if (this.content instanceof String)
return ((String)this.content).getBytes();
if (this.content instanceof Document)
try {
Document doc = (Document)this.content;
prepareManifest(doc);
return CommonXMLUtils.doc2string(doc).getBytes();
} catch (Exception e) {
e.printStackTrace();
}
return new byte[] {};
}
protected void prepareManifest(Document doc) {
Manifest m = new Manifest();
m.getMainAttributes().putValue("Manifest-Version", "2");
m.getMainAttributes().putValue(Constants.BUNDLE_MANIFESTVERSION, "2");
m.getMainAttributes().putValue(Constants.BUNDLE_SYMBOLICNAME
, this.coordinates.getGroupId() + "." + this.coordinates.getArtifactId());
m.getMainAttributes().putValue(Constants.BUNDLE_NAME
, this.coordinates.getGroupId() + "." + this.coordinates.getArtifactId());
m.getMainAttributes().putValue(Constants.BUNDLE_VERSION, this.coordinates.getVersion().replaceAll("-", "."));
m.getMainAttributes().putValue(Constants.DYNAMICIMPORT_PACKAGE, "*");
m.getMainAttributes().putValue(Artifact.MANIFEST_HEADER_ENTAXY_BUNLDE, "true");
m.getMainAttributes().putValue(Artifact.MANIFEST_HEADER_ENTAXY_RUNTIME, "true");
NodeList l = doc.getElementsByTagName("manifest");
if (l != null) {
for (int i = 0; i < l.getLength(); i++) {
Element e = (Element) l.item(i);
String text = e.getTextContent();
Properties props = new Properties();
try {
props.load(new ByteArrayInputStream(text.trim().getBytes()));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Enumeration en = props.propertyNames();
while (en.hasMoreElements()) {
String k = (String) en.nextElement();
String v = props.getProperty(k);
m.getMainAttributes().putValue(k, v);
}
e.getParentNode().removeChild(e);
}
}
// add capabilities info
String requiredCapabilities = getRequiredCapabilitiesValue();
String providedCapabilities = getProvidedCapabilitiesValue();
if (CommonUtils.isValid(requiredCapabilities)) {
Object v = m.getMainAttributes().get(Constants.REQUIRE_CAPABILITY);
String value = (v==null?"":v.toString());
if (CommonUtils.isValid(value))
value += "," + requiredCapabilities;
else
value = requiredCapabilities;
m.getMainAttributes().putValue(Constants.REQUIRE_CAPABILITY, value);
}
if (CommonUtils.isValid(providedCapabilities)) {
Object v = m.getMainAttributes().get(Constants.PROVIDE_CAPABILITY);
String value = (v==null?"":v.toString());
if (CommonUtils.isValid(value))
value += "," + providedCapabilities;
else
value = providedCapabilities;
m.getMainAttributes().putValue(Constants.PROVIDE_CAPABILITY, value);
}
ByteArrayOutputStream bos = new ByteArrayOutputStream();
String manifestContent = "";
try {
m.write(bos);
manifestContent = bos.toString(StandardCharsets.ISO_8859_1);
manifestContent = manifestContent.replaceAll("\r", "").replaceAll("\n ", "");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Element manifest = doc.createElementNS("http://karaf.apache.org/xmlns/deployer/blueprint/v1.0.0", "manifest");
manifest.setTextContent(manifestContent);
doc.getDocumentElement().insertBefore(manifest, doc.getDocumentElement().getFirstChild());
// copy manifest data to artifact properties
for (Object key: m.getMainAttributes().keySet()) {
this.properties.put(key.toString(), m.getMainAttributes().get(key));
}
}
}

View File

@ -0,0 +1,30 @@
/*-
* ~~~~~~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;
import org.osgi.resource.Capability;
public interface CapabilityDescriptor extends Capability {
public CapabilityDescriptor namespace(String namespace);
public CapabilityDescriptor attribute(String name, String value);
public CapabilityDescriptor attribute(String name, String value, String type);
}

View File

@ -0,0 +1,179 @@
/*-
* ~~~~~~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;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
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.impl.CapabilityDescriptorImpl;
public class DefaultArtifact implements Artifact {
protected ArtifactCoordinates coordinates;
protected ArtifactSupport artifactSupport = null;
protected Object content = null;
protected String category = Artifact.ARTIFACT_CATEGORY_UNKNOWN;
protected Map<String, Object> properties = new HashMap<>();
protected List<Class<?>> supportedContentClasses = new ArrayList<>();
protected Map<String, CapabilityDescriptorImpl> requiredCapabilities = new HashMap<>();
protected Map<String, CapabilityDescriptorImpl> providedCapabilities = new HashMap<>();
public DefaultArtifact() {
this.coordinates = new ArtifactCoordinates();
this.artifactSupport = this.getClass().getAnnotation(ArtifactSupport.class);
initArtifact();
}
protected void initArtifact() {
if (artifactSupport != null) {
this.coordinates.type(artifactSupport.defaultArtifactType());
this.coordinates.classifier(artifactSupport.defaultArtifactClassifier());
this.setCategory(artifactSupport.supportedCategory());
if (this.artifactSupport.supportedContentClasses() != null)
for (int i=0; i<this.artifactSupport.supportedContentClasses().length; i++)
this.supportedContentClasses.add(this.artifactSupport.supportedContentClasses()[i]);
}
}
@Override
public ArtifactCoordinates getCoordinates() {
return coordinates;
}
public Object getContent() {
return content;
}
public void setContent(Object content) {
if (content == null)
setNullContent();
else {
if (artifactSupport != null) {
checkSetContent(content);
} else
this.content = content;
}
}
protected void setNullContent() {
this.content = null;
}
protected void checkSetContent(Object content) {
// TODO throw exception if content suites none of the supported clssses
if (this.supportedContentClasses.contains(content.getClass()))
this.content = content;
/*
* Class<?>[] supportedContentTypes = Arrays.copyOf(
* this.artifactSupport.supportedContentClasses(),
* this.artifactSupport.supportedContentClasses().length); for (int i=0;
* i<supportedContentTypes.length; i++) { if
* (supportedContentTypes[i].isAssignableFrom(content.getClass())) this.content
* = content; break; }
*/ }
@Override
public String getCategory() {
return this.category;
}
public void setCategory(String category) {
if (!Strings.isNullOrEmpty(category))
this.category = category;
else
this.category = Artifact.ARTIFACT_CATEGORY_UNKNOWN;
}
@Override
public void toFile(File destination) {
if (this.content != null) {
try {
FileWriter writer = new FileWriter(destination);
writer.write(this.content.toString());
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public byte[] asByteArray() {
return null;
}
@Override
public Map<String, Object> getProperties() {
return properties;
}
@Override
public CapabilityDescriptor provideCapability(String namespace) {
if (!this.providedCapabilities.containsKey(namespace))
this.providedCapabilities.put(namespace, new CapabilityDescriptorImpl(namespace));
return this.providedCapabilities.get(namespace);
}
@Override
public CapabilityDescriptor requireCapability(String namespace) {
if (!this.requiredCapabilities.containsKey(namespace))
this.requiredCapabilities.put(namespace, new CapabilityDescriptorImpl(namespace));
return this.requiredCapabilities.get(namespace);
}
protected String getRequiredCapabilitiesValue() {
return getCapabilitiesValue(requiredCapabilities);
}
protected String getProvidedCapabilitiesValue() {
return getCapabilitiesValue(providedCapabilities);
}
protected String getCapabilitiesValue(Map<String, CapabilityDescriptorImpl> data) {
String result = "";
for (Map.Entry<String, CapabilityDescriptorImpl> entry: data.entrySet()) {
if (!result.isEmpty())
result += ",";
result += entry.getKey();
String attributes = entry.getValue().getAttributesAsString();
if (!attributes.isEmpty())
result += ";" + attributes;
}
return result;
}
}

View File

@ -0,0 +1,28 @@
/*-
* ~~~~~~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;
public interface DeployedArtifact {
public Artifact getArtifact();
public String getLocation();
}

View File

@ -0,0 +1,40 @@
/*-
* ~~~~~~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.annotation;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target(TYPE)
@Inherited
public @interface ArtifactSupport {
String supportedCategory();
Class<?>[] supportedContentClasses() default {java.lang.Object.class};
String defaultArtifactType() default "";
String defaultArtifactClassifier() default "";
}

View File

@ -0,0 +1,118 @@
/*-
* ~~~~~~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.impl;
import java.util.HashMap;
import java.util.Map;
import org.osgi.resource.Resource;
import ru.entaxy.platform.core.artifact.CapabilityDescriptor;
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;
String value;
Object typedValue;
public AttributeDescriptor(String value) {
this(value, "String");
}
public AttributeDescriptor(String value, String type) {
this.type = type;
this.value = value;
// TODO convert types if needed
this.typedValue = value;
}
}
public CapabilityDescriptorImpl() {
// TODO Auto-generated constructor stub
}
public CapabilityDescriptorImpl(String namespace) {
this();
namespace(namespace);
}
public String getAttributesAsString() {
String result = "";
for (Map.Entry<String, AttributeDescriptor> entry: this.attributes.entrySet()) {
if (!result.isEmpty())
result += ";";
result += entry.getKey();
if (!"String".equals(entry.getValue().type))
result += ":" + entry.getValue().type;
result += "=" + entry.getValue().value;
}
return result;
}
@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().typedValue);
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, String value) {
this.attributes.put(name, new AttributeDescriptor(value));
return this;
}
@Override
public CapabilityDescriptor attribute(String name, String value, String type) {
this.attributes.put(name, new AttributeDescriptor(value, type));
return this;
}
}

View File

@ -0,0 +1,32 @@
/*-
* ~~~~~~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.installer;
import ru.entaxy.platform.core.artifact.installer.builder.Installer;
public interface ArtifactInstaller<T extends Installer<?>> {
public static final String ARTIFACT_INSTALLER_LOCAL = "local";
public static final String ARTIFACT_INSTALLER_CLUSTER = "cluster";
public String getName();
public T createInstaller();
}

View File

@ -0,0 +1,26 @@
/*-
* ~~~~~~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.installer.builder;
public interface ClusterInstaller extends Installer<ClusterInstaller> {
public ClusterInstaller groups(String...groups);
}

View File

@ -0,0 +1,25 @@
/*-
* ~~~~~~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.installer.builder;
public interface CommonInstaller {
public InstallationResult install();
public InstallationResult uninstall();
}

View File

@ -0,0 +1,54 @@
/*-
* ~~~~~~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.installer.builder;
import java.util.List;
import java.util.Map;
public interface InstallationResult {
public static final String PROP_BUNDLE_STATUS = "BundleStatus";
public enum Result {
INSTALLED,
UPDATED,
NOT_CHANGED,
STARTED,
STOPPED,
UNINSTALLED,
FAILED
}
public Result getResult();
public Map<String, Object> getProperties();
public Object getObject();
public List<InstallationResult> getSubResults();
public Throwable getError();
public String getMessage();
public default boolean isSuccessful() {
return !Result.FAILED.equals(getResult());
}
}

View File

@ -0,0 +1,39 @@
/*-
* ~~~~~~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.installer.builder;
import ru.entaxy.platform.core.artifact.DeployedArtifact;
import ru.entaxy.platform.core.artifact.installer.builder.typed.TypedInstaller;
import ru.entaxy.platform.core.artifact.legacy.BundleController;
public interface Installer<S extends Installer<S>> extends CommonInstaller {
public S artifact(DeployedArtifact artifact);
public S sourceLocation(String sourceLocation);
public S bundleName(String bundleName);
public <T extends TypedInstaller> T typed(Class<T> type);
// for backward compatibility
// TODO to be removed in the future
public BundleController bundleController();
}

View File

@ -0,0 +1,27 @@
/*-
* ~~~~~~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.installer.builder;
public interface Installers {
public LocalInstaller local();
public ClusterInstaller cluster(String... groupName);
}

View File

@ -0,0 +1,27 @@
/*-
* ~~~~~~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.installer.builder;
public interface InstallersWithDefaults extends Installers {
public Installers useDefaults();
public Installer<?> byName(String name);
}

View File

@ -0,0 +1,24 @@
/*-
* ~~~~~~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.installer.builder;
public interface LocalInstaller extends Installer<LocalInstaller> {
}

View File

@ -0,0 +1,299 @@
/*-
* ~~~~~~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.installer.builder.impl;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import org.apache.karaf.bundle.command.Install;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.platform.core.artifact.DeployedArtifact;
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.typed.BundleInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.typed.TypedInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.TypedInstallerHelper;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.TypedInstallerImpl;
import ru.entaxy.platform.core.artifact.legacy.BundleController;
public abstract class AbstractInstaller<T extends Installer<T>, H extends TypedInstallerHelper>
implements BundleController {
private static final Logger log = LoggerFactory.getLogger(AbstractInstaller.class);
protected DeployedArtifact artifact = null;
protected String sourceLocation = null;
protected String bundleName = null;
protected Map<String, Class<? extends TypedInstallerImpl>> typedInstallerClasses = new HashMap<>();
protected Map<Class<? extends TypedInstallerImpl>, Class<? extends H>> typedHelpeClasses = new HashMap<>();
// for BundleInstaller implementation
protected BundleInstaller bundleInstaller = null;
protected TypedInstallerImpl typedInstaller = null;
protected AbstractInstaller() {
this.typedInstallerClasses = new HashMap<>();
this.typedHelpeClasses = new HashMap<>();
}
protected void doCreateTypedInstaller(Class<? extends TypedInstallerImpl> clazz) {
Constructor<?> constructor;
try {
constructor = clazz.getConstructor();
this.typedInstaller = (TypedInstallerImpl)constructor.newInstance();
} catch (NoSuchMethodException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void createTypedInstaller() {
Class<? extends TypedInstallerImpl> clazz =
artifact==null
?null
:typedInstallerClasses.get(artifact.getArtifact().getCategory());
if (clazz == null)
// TODO throw exception
return;
doCreateTypedInstaller(clazz);
if (this.typedInstaller != null) {
initTypedInstaller();
}
}
protected void findTypedInstaller(Class<?> type) {
Class<? extends TypedInstallerImpl> clazz = null;
for (Class<? extends TypedInstallerImpl> cl : typedInstallerClasses.values())
if ((cl != null) && type.isAssignableFrom(cl)) {
clazz = cl;
break;
}
if (clazz == null)
// TODO throw exception
return;
doCreateTypedInstaller(clazz);
if (this.typedInstaller != null) {
initTypedInstaller();
}
}
protected H createHelper() {
Class<? extends H> clazz = typedHelpeClasses.get(typedInstaller.getClass());
if (clazz == null)
return createDefaultHelper();
Constructor<?> constructor;
String errorMessage = "Error creating typed installer helper";
try {
constructor = clazz.getConstructor();
return (H)constructor.newInstance();
} catch (NoSuchMethodException | SecurityException e) {
log.error(errorMessage, e);
} catch (InstantiationException e) {
log.error(errorMessage, e);
} catch (IllegalAccessException e) {
log.error(errorMessage, e);
} catch (IllegalArgumentException e) {
log.error(errorMessage, e);
} catch (InvocationTargetException e) {
log.error(errorMessage, e);
}
return createDefaultHelper();
}
protected abstract H createDefaultHelper();
protected void refreshTypedInstaller() {
this.typedInstaller.clearInstaller();
this.typedInstaller.setArtifact(this.artifact);
this.typedInstaller.setSourceLocation(this.sourceLocation);
this.typedInstaller.setBundleName(this.bundleName);
}
protected void initTypedInstaller() {
refreshTypedInstaller();
H helper = createHelper();
initHelper(helper);
this.typedInstaller.setHelper(helper);
}
protected void initHelper(H helper) {
};
public <S extends TypedInstaller> S typed(Class<S> type) {
if (this.typedInstaller == null)
createTypedInstaller();
if (this.typedInstaller == null)
findTypedInstaller(type);
if (this.typedInstaller == null)
// TODO throw exception
return null;
if (!type.isAssignableFrom(this.typedInstaller.getClass()))
// TODO throw exception
return null;
return type.cast(this.typedInstaller);
}
public InstallationResult install() {
if (typedInstaller == null) {
createTypedInstaller();
}
if (typedInstaller != null)
return typedInstaller.install();
return null;
}
public InstallationResult uninstall() {
if (typedInstaller == null) {
createTypedInstaller();
}
if (typedInstaller != null)
return typedInstaller.uninstall();
return null;
}
public T artifact(DeployedArtifact artifact) {
setArtifact(artifact);
return (T)this;
}
public T sourceLocation(String sourceLocation) {
setSourceLocation(sourceLocation);
return (T)this;
}
public void setArtifact(DeployedArtifact artifact) {
this.artifact = artifact;
}
public void setSourceLocation(String sourceLocation) {
this.sourceLocation = sourceLocation;
}
public T bundleName(String bundleName) {
setBundleName(bundleName);
return (T) this;
}
public void setBundleName(String bundleName) {
this.bundleName = bundleName;
}
public BundleController bundleController() {
return (BundleController) this;
}
protected BundleInstaller createBundleInstaller() {
return typed(BundleInstaller.class);
}
protected void initBundleInstaller() {
if (this.bundleInstaller == null)
this.bundleInstaller = createBundleInstaller();
}
protected void clear() {
this.artifact = null;
this.sourceLocation = null;
this.bundleName = null;
}
/*
* BundleController implementation
*/
public String installAndStartBundle(String bundleUrl, String bundleName) throws Exception {
initBundleInstaller();
clear();
this.sourceLocation(bundleUrl);
refreshTypedInstaller();
InstallationResult result = this.bundleInstaller.update(bundleName).installOnlyIfMissing().start().install();
return result.getProperties()
.getOrDefault(InstallationResult.PROP_BUNDLE_STATUS, "RESOLVED")
.toString();
};
public void installBundle(String bundleUrl) throws Exception {
initBundleInstaller();
clear();
this.sourceLocation(bundleUrl);
refreshTypedInstaller();
this.bundleInstaller.update().installOnlyIfMissing().install();
};
public String updateBundle(String bundleName) throws Exception {
initBundleInstaller();
clear();
InstallationResult result = this.bundleInstaller.update(bundleName).updateOnly().install();
return result.getProperties()
.getOrDefault(InstallationResult.PROP_BUNDLE_STATUS, "Resolved")
.toString();
};
public String startBundle(String bundleName) throws Exception {
initBundleInstaller();
clear();
bundleName(bundleName);
refreshTypedInstaller();
InstallationResult result = this.bundleInstaller.startOnly().install();
return result.getProperties().getOrDefault(InstallationResult.PROP_BUNDLE_STATUS
, "Resolved").toString();
};
public String stopBundle(String bundleName) throws Exception {
initBundleInstaller();
clear();
bundleName(bundleName);
refreshTypedInstaller();
InstallationResult result = this.bundleInstaller.stopOnly().install();
return result.getProperties().getOrDefault(InstallationResult.PROP_BUNDLE_STATUS
, "Resolved").toString();
};
public void uninstallBundle(String bundleName) throws Exception {
initBundleInstaller();
clear();
bundleName(bundleName);
refreshTypedInstaller();
this.bundleInstaller.uninstall();
};
}

View File

@ -0,0 +1,166 @@
/*-
* ~~~~~~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.installer.builder.impl;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import ru.entaxy.platform.core.artifact.installer.builder.InstallationResult;
public class InstallationResultImpl implements InstallationResult {
public static InstallationResultImpl create() {
return new InstallationResultImpl();
}
protected Result result = null;
protected final Map<String, Object> properties = new HashMap<>();
protected Object object = null;
protected final List<InstallationResult> subResults = new LinkedList<>();
protected Throwable error = null;
protected String message = null;
@Override
public Result getResult() {
return this.result;
}
@Override
public Map<String, Object> getProperties() {
return this.properties;
}
@Override
public Object getObject() {
return this.object;
}
@Override
public List<InstallationResult> getSubResults() {
return this.subResults;
}
@Override
public Throwable getError() {
return this.error;
}
@Override
public String getMessage() {
return this.message;
}
public InstallationResultImpl result(Result result) {
this.result = result;
return this;
}
public InstallationResultImpl object(Object object) {
this.object = object;
return this;
}
public InstallationResultImpl property(String key, Object value) {
this.properties.put(key, value);
return this;
}
public InstallationResultImpl error(Throwable error) {
this.error = error;
return this;
}
public InstallationResultImpl subResult(InstallationResult subresult) {
this.subResults.add(subresult);
return this;
}
public InstallationResultImpl message(String message) {
this.message = message;
return this;
}
public InstallationResultImpl notChanged() {
return this.result(Result.NOT_CHANGED);
}
public InstallationResultImpl installed() {
return this.result(Result.INSTALLED);
}
public InstallationResultImpl installed(Object object) {
object(object);
return this.result(Result.INSTALLED);
}
public InstallationResultImpl uninstalled() {
return this.result(Result.UNINSTALLED);
}
public InstallationResultImpl uninstalled(Object object) {
object(object);
return this.result(Result.UNINSTALLED);
}
public InstallationResultImpl updated() {
return this.result(Result.UPDATED);
}
public InstallationResultImpl updated(Object object) {
object(object);
return this.result(Result.UPDATED);
}
public InstallationResultImpl started() {
return this.result(Result.STARTED);
}
public InstallationResultImpl started(Object object) {
object(object);
return this.result(Result.STARTED);
}
public InstallationResultImpl stopped() {
return this.result(Result.STOPPED );
}
public InstallationResultImpl stopped(Object object) {
object(object);
return this.result(Result.STOPPED);
}
public InstallationResultImpl failed() {
return this.result(Result.FAILED);
}
public InstallationResultImpl failed(String message) {
message(message);
return this.result(Result.FAILED);
}
}

View File

@ -0,0 +1,77 @@
/*-
* ~~~~~~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.installer.builder.impl;
import ru.entaxy.platform.core.artifact.installer.ArtifactInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.ClusterInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.Installers;
import ru.entaxy.platform.core.artifact.installer.builder.LocalInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.impl.cluster.ClusterInstallerWrapperImpl;
public class InstallersImpl implements Installers {
protected ArtifactInstaller<LocalInstaller> local = null;
protected ArtifactInstaller<ClusterInstaller> cluster = null;
protected boolean localOnlyMode = false;
@Override
public LocalInstaller local() {
if (local == null)
// TODO throw exception
return null;
return local.createInstaller();
}
@Override
public ClusterInstaller cluster(String... groupName) {
if (this.localOnlyMode)
return new ClusterInstallerWrapperImpl(this.local());
if (cluster == null)
// TODO throw exception
return null;
return cluster.createInstaller().groups(groupName);
}
public ArtifactInstaller<LocalInstaller> getLocal() {
return local;
}
public void setLocal(ArtifactInstaller<LocalInstaller> local) {
this.local = local;
}
public ArtifactInstaller<ClusterInstaller> getCluster() {
return cluster;
}
public void setCluster(ArtifactInstaller<ClusterInstaller> cluster) {
this.cluster = cluster;
}
public boolean isLocalOnlyMode() {
return localOnlyMode;
}
public void setLocalOnlyMode(boolean localOnlyMode) {
this.localOnlyMode = localOnlyMode;
}
}

View File

@ -0,0 +1,102 @@
/*-
* ~~~~~~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.installer.builder.impl;
import java.util.HashMap;
import java.util.Map;
import ru.entaxy.platform.core.artifact.installer.ArtifactInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.ClusterInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.Installer;
import ru.entaxy.platform.core.artifact.installer.builder.Installers;
import ru.entaxy.platform.core.artifact.installer.builder.InstallersWithDefaults;
import ru.entaxy.platform.core.artifact.installer.builder.LocalInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.impl.cluster.ClusterInstallerWrapperImpl;
public class InstallersWithDefaultsImpl implements InstallersWithDefaults {
protected InstallersImpl defaults = null;
protected Map<String, ArtifactInstaller<?>> installers = new HashMap<>();
protected ArtifactInstaller<LocalInstaller> local = null;
protected ArtifactInstaller<ClusterInstaller> cluster = null;
protected boolean localOnlyMode = false;
@Override
public LocalInstaller local() {
if (this.local == null)
if (defaults != null)
return defaults.local();
return this.local.createInstaller();
}
@Override
public ClusterInstaller cluster(String... groupName) {
if (this.localOnlyMode)
return new ClusterInstallerWrapperImpl(this.local());
if (this.cluster == null)
if (defaults != null)
return defaults.cluster(groupName);
return this.cluster.createInstaller().groups(groupName);
}
@Override
public Installer<?> byName(String name) {
if (ArtifactInstaller.ARTIFACT_INSTALLER_LOCAL.equals(name))
return local();
if (ArtifactInstaller.ARTIFACT_INSTALLER_CLUSTER.equals(name))
return cluster();
if (!this.installers.containsKey(name))
return null;
return this.installers.get(name).createInstaller();
}
@SuppressWarnings("unchecked")
public void addInstaller(ArtifactInstaller<?> installer) {
installers.put(installer.getName(), installer);
if (ArtifactInstaller.ARTIFACT_INSTALLER_LOCAL.equalsIgnoreCase(installer.getName()))
this.local = (ArtifactInstaller<LocalInstaller>)installer;
if (ArtifactInstaller.ARTIFACT_INSTALLER_CLUSTER.equalsIgnoreCase(installer.getName()))
this.cluster = (ArtifactInstaller<ClusterInstaller>)installer;
}
@Override
public Installers useDefaults() {
if (defaults == null)
return this;
return defaults;
}
public void setDefaults(InstallersImpl defaults) {
this.defaults = defaults;
}
public boolean isLocalOnlyMode() {
return localOnlyMode;
}
public void setLocalOnlyMode(boolean localOnlyMode) {
this.localOnlyMode = localOnlyMode;
}
}

View File

@ -0,0 +1,286 @@
/*-
* ~~~~~~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.installer.builder.impl.cluster;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.TabularData;
import org.apache.karaf.cellar.bundle.management.CellarBundleMBean;
import org.osgi.framework.Constants;
import ru.entaxy.esb.system.common.exception.BundleNotFound;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.base.support.osgi.OSGIUtils;
import ru.entaxy.platform.core.artifact.installer.builder.InstallationResult;
import ru.entaxy.platform.core.artifact.installer.builder.impl.InstallationResultImpl;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.CommonBundleInstallerHelper;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.CommonBundleInstallerHelperConfig;
public class ClusterCommonBundleInstallerHelper extends ClusterTypedInstallerHelper
implements CommonBundleInstallerHelper {
protected CommonBundleInstallerHelperConfig config;
@Override
public void setConfig(CommonBundleInstallerHelperConfig config) {
this.config = config;
}
@Override
public InstallationResultImpl install(InstallationResultImpl installationResult) {
//ClusterTypedInstallerHelper _helper = (ClusterTypedInstallerHelper)helper;
// InstallationResultImpl installationResult = InstallationResultImpl
// .create()
// .property("artifact", artifact);
CompositeData existingBundle = null;
List<String> groupsToInstall = new ArrayList<>();
for (String groupName: getGroups())
if (checkGroup(groupName))
if (!groupsToInstall.contains(groupName))
groupsToInstall.add(groupName);
if (groupsToInstall.size()==0) {
return installationResult.failed("No groups to install to");
}
CellarBundleMBean bundleService = OSGIUtils.getService(CellarBundleMBean.class);
if (bundleService == null) {
// TODO throw exception
return installationResult
.failed("Can't install/update: CellarBundleMBean not available");
}
// TODO decide if we really need several grouos
// now we use only the first one
String groupToInstall = groupsToInstall.get(0);
if (this.config.isUpdate() || this.config.isUpdateOnly() || this.config.isInstallOnlyIfMissing()
|| this.config.isStartBundleOnly() || this.config.isStopBundleOnly()) {
String bundleId = this.config.getBundleId();
if (!CommonUtils.isValid(bundleId)) {
// TODO throw exception
return installationResult
.failed("Can't update: bundleId can not be defined");
}
// if not bundles found BundleService throws exception
try {
existingBundle = getBundleData(bundleId, bundleService, groupToInstall);
} catch (Exception e) {
// NOOP
}
if (existingBundle != null) {
installationResult.object(existingBundle);
if (this.config.isInstallOnlyIfMissing()) {
installationResult.notChanged();
} else
if (this.config.isUpdate() || this.config.isUpdateOnly()) {
try {
if (this.config.isStartBundle())
bundleService.updateStart(groupToInstall, bundleId, this.config.getBundleLocation());
else
bundleService.update(groupToInstall, bundleId, this.config.getBundleLocation());
installationResult.updated();
} catch (Exception e) {
installationResult.failed().error(e);
}
} else
if (this.config.isStartBundleOnly()) {
try {
bundleService.start(groupToInstall, bundleId);
installationResult.started()
.property(InstallationResult.PROP_BUNDLE_STATUS
, getStatusByName(bundleId, bundleService, groupToInstall));
} catch (Exception e) {
// TODO Auto-generated catch block
installationResult.failed().error(e);
}
} else
if (this.config.isStopBundleOnly()) {
try {
bundleService.stop(groupToInstall, bundleId);
installationResult.stopped()
.property(InstallationResult.PROP_BUNDLE_STATUS
, getStatusByName(bundleId, bundleService, groupToInstall));
} catch (Exception e) {
// TODO Auto-generated catch block
installationResult.failed().error(e);
}
}
return installationResult;
}
}
if (this.config.isUpdateOnly()) {
return installationResult.failed("UpdateOnly failed: bundle to update not found");
}
try {
if (this.config.getStartLevel() > 0) {
bundleService.install(groupToInstall, this.config.getBundleLocation()
, this.config.getStartLevel(), this.config.isStartBundle());
} else {
bundleService.install(groupToInstall, this.config.getBundleLocation(), this.config.isStartBundle());
}
installationResult.installed()
.property(InstallationResult.PROP_BUNDLE_STATUS
, getStatusByLocation(this.config.getBundleLocation(), bundleService, groupToInstall));
} catch (Exception e) {
installationResult.error(e)
.failed("Installing bundle failed: Exception");
}
return installationResult.installed();
}
@Override
public InstallationResultImpl uninstall(InstallationResultImpl installationResult) {
CompositeData existingBundle = null;
List<String> groupsToInstall = new ArrayList<>();
for (String groupName: getGroups())
if (checkGroup(groupName))
if (!groupsToInstall.contains(groupName))
groupsToInstall.add(groupName);
if (groupsToInstall.size()==0) {
return installationResult.failed("No groups to install to");
}
CellarBundleMBean bundleService = OSGIUtils.getService(CellarBundleMBean.class);
if (bundleService == null) {
// TODO throw exception
return installationResult
.failed("Can't install/update: CellarBundleMBean not available");
}
// TODO decide if we really need several grouos
// now we use only the first one
String groupToInstall = groupsToInstall.get(0);
String bundleId = this.config.getBundleId();
if (!CommonUtils.isValid(bundleId)) {
// TODO throw exception
return installationResult
.failed("Can't update: bundleId can not be defined");
}
// if not bundles found BundleService throws exception
try {
existingBundle = getBundleData(bundleId, bundleService, groupToInstall);
} catch (Exception e) {
// NOOP
}
if (existingBundle != null) {
try {
bundleService.uninstall(groupToInstall, bundleId);
installationResult.uninstalled();
} catch (Exception e) {
installationResult.failed("Failed uninstalling bundle [" + bundleId + "]").error(e);
}
} else {
installationResult.notChanged().message("BUNDLE NOT FOUND");
}
return installationResult;
}
private String getStatusByLocation(String bundleLocation
, CellarBundleMBean cellarBundleMBean
, String cellarGroup) throws Exception {
TabularData tabularData = cellarBundleMBean.getBundles(cellarGroup);
String status = null;
for (Object value : tabularData.values()) {
CompositeData compositeData = (CompositeData) value;
if (bundleLocation.equals(compositeData.get("location"))) {
status = compositeData.get("status").toString();
}
}
if (status == null) {
throw new BundleNotFound();
}
return status.toUpperCase();
}
private String getStatusByName(String bundleName
, CellarBundleMBean cellarBundleMBean
, String cellarGroup) throws Exception {
CompositeData data = getBundleData(bundleName, cellarBundleMBean, cellarGroup);
if ( (data != null) && (data.containsKey("status"))) {
Object obj = data.get("status");
return obj == null?null:obj.toString();
};
return null;
}
private List<CompositeData> getBundlesData(String symbolicName
, CellarBundleMBean cellarBundleMBean
, String cellarGroup) throws Exception {
TabularData tabularData = cellarBundleMBean.getBundles(cellarGroup);
List<CompositeData> results = new LinkedList<>();
for (Object value : tabularData.values()) {
CompositeData compositeData = (CompositeData) value;
if (symbolicName.equals(compositeData.get("name")) || symbolicName.equals(compositeData.get("symbolic_name"))) {
results.add(compositeData);
}
}
return results;
}
private CompositeData getBundleData(String symbolicName
, CellarBundleMBean cellarBundleMBean
, String cellarGroup) throws Exception {
List<CompositeData> results = getBundlesData(symbolicName, cellarBundleMBean, cellarGroup);
if (results.size()==0)
return null;
else
return results.get(0);
}
}

View File

@ -0,0 +1,81 @@
/*-
* ~~~~~~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.installer.builder.impl.cluster;
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.LocalInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.typed.TypedInstaller;
import ru.entaxy.platform.core.artifact.legacy.BundleController;
public class ClusterInstallerWrapperImpl implements ClusterInstaller {
protected LocalInstaller delegate;
public ClusterInstallerWrapperImpl(LocalInstaller delegate) {
this.delegate = delegate;
}
@Override
public ClusterInstaller artifact(DeployedArtifact artifact) {
this.delegate.artifact(artifact);
return this;
}
@Override
public ClusterInstaller sourceLocation(String sourceLocation) {
this.delegate.sourceLocation(sourceLocation);
return this;
}
@Override
public ClusterInstaller bundleName(String bundleName) {
this.delegate.bundleName(bundleName);
return this;
}
@Override
public <T extends TypedInstaller> T typed(Class<T> type) {
return this.delegate.typed(type);
}
@Override
public BundleController bundleController() {
return this.delegate.bundleController();
}
@Override
public InstallationResult install() {
return this.delegate.install();
}
@Override
public InstallationResult uninstall() {
return this.delegate.uninstall();
}
@Override
public ClusterInstaller groups(String... groups) {
// NOOP
return this;
}
}

View File

@ -0,0 +1,60 @@
/*-
* ~~~~~~licensing~~~~~~
* artifact-management
* ==========
* Copyright (C) 2020 - 2021 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.platform.core.artifact.installer.builder.impl.cluster;
import java.util.ArrayList;
import java.util.List;
import org.apache.karaf.cellar.core.GroupManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.platform.base.support.osgi.OSGIUtils;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.TypedInstallerHelper;
public class ClusterTypedInstallerHelper extends TypedInstallerHelper {
private static final Logger log = LoggerFactory.getLogger(ClusterTypedInstallerHelper.class);
protected List<String> groups = new ArrayList<>();
public void setGroups(List<String> groups) {
this.groups = groups;
}
public List<String> getGroups() {
return groups;
}
protected boolean checkGroup(String groupName) {
GroupManager groupManager = OSGIUtils.getService(GroupManager.class);
if (groupManager == null)
try {
groupManager = OSGIUtils.services().ofClass(GroupManager.class).waitService(20000).<GroupManager>get();
if (groupManager == null)
throw new Exception("Service not found in 20000 ms");
} catch (Exception e) {
log.error("ERROR getting GroupManager service: ", e);
return false;
}
return (groupManager.findGroupByName(groupName) != null);
}
}

View File

@ -0,0 +1,85 @@
/*-
* ~~~~~~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.installer.builder.impl.cluster;
import java.util.Arrays;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.platform.core.artifact.Artifact;
import ru.entaxy.platform.core.artifact.installer.builder.ClusterInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.impl.AbstractInstaller;
public class DefaultCellarInstaller extends AbstractInstaller<ClusterInstaller, ClusterTypedInstallerHelper> implements ClusterInstaller {
private static final Logger log = LoggerFactory.getLogger(DefaultCellarInstaller.class);
// protected DeployedArtifact artifact = null;
protected List<String> groups;
// TODO read default group name from config
protected String defaultGroupName = "default";
public DefaultCellarInstaller() {
super();
this.typedInstallerClasses.put(Artifact.ARTIFACT_CATEGORY_BLUEPRINT, ru.entaxy.platform.core.artifact.installer.builder.typed.impl.BlueprintInstallerImpl.class);
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
, ClusterCommonBundleInstallerHelper.class);
this.typedHelpeClasses.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
, ClusterCommonBundleInstallerHelper.class);
initGroups();
}
protected void initGroups() {
groups = Arrays.asList(new String[] {this.defaultGroupName});
}
@Override
protected ClusterTypedInstallerHelper createDefaultHelper() {
return new ClusterTypedInstallerHelper();
}
@Override
protected void initHelper(ClusterTypedInstallerHelper helper) {
helper.setGroups(groups);
}
@Override
public ClusterInstaller groups(String... groups) {
if (groups!=null && groups.length>0)
this.groups.addAll(Arrays.asList((String[])groups));
else
initGroups();
return this;
}
}

View File

@ -0,0 +1,51 @@
/*-
* ~~~~~~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.installer.builder.impl.local;
import ru.entaxy.platform.core.artifact.Artifact;
import ru.entaxy.platform.core.artifact.installer.builder.LocalInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.impl.AbstractInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.BlueprintInstallerImpl;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.BundleInstallerImpl;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.JarInstallerImpl;
public class DefaultLocalInstaller extends AbstractInstaller<LocalInstaller, LocalTypedInstallerHelper>
implements LocalInstaller {
public DefaultLocalInstaller() {
super();
this.typedInstallerClasses.put(Artifact.ARTIFACT_CATEGORY_BLUEPRINT, BlueprintInstallerImpl.class);
this.typedInstallerClasses.put(Artifact.ARTIFACT_CATEGORY_BUNDLE, BundleInstallerImpl.class);
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);
}
@Override
protected LocalTypedInstallerHelper createDefaultHelper() {
return new LocalTypedInstallerHelper();
}
}

View File

@ -0,0 +1,289 @@
/*-
* ~~~~~~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.installer.builder.impl.local;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.Arrays;
import org.apache.karaf.bundle.core.BundleService;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.startlevel.BundleStartLevel;
import org.osgi.framework.wiring.FrameworkWiring;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.base.support.osgi.BundleUtils;
import ru.entaxy.platform.base.support.osgi.OSGIUtils;
import ru.entaxy.platform.core.artifact.installer.ArtifactInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.InstallationResult;
import ru.entaxy.platform.core.artifact.installer.builder.impl.InstallationResultImpl;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.CommonBundleInstallerHelper;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.CommonBundleInstallerHelperConfig;
public class LocalCommonBundleInstallerHelper extends LocalTypedInstallerHelper
implements CommonBundleInstallerHelper {
protected CommonBundleInstallerHelperConfig config;
public static String bundleStatus(int bundleStatus) {
if (bundleStatus == Bundle.ACTIVE)
return "ACTIVE";
if (bundleStatus == Bundle.INSTALLED)
return "INSTALLED";
if (bundleStatus == Bundle.RESOLVED)
return "RESOLVED";
if (bundleStatus == Bundle.STARTING)
return "STARTING";
if (bundleStatus == Bundle.STOPPING)
return "STOPPING";
if (bundleStatus == Bundle.UNINSTALLED)
return "UNINSTALLED";
return "INSTALLED";
}
@Override
public void setConfig(CommonBundleInstallerHelperConfig config) {
this.config = config;
}
@Override
public InstallationResultImpl install(InstallationResultImpl installationResult) {
Bundle existingBundle = null;
if (this.config.isUpdate() || this.config.isUpdateOnly() || this.config.isInstallOnlyIfMissing()
|| this.config.isStartBundleOnly() || this.config.isStopBundleOnly()) {
BundleService bundleService = OSGIUtils.getService(BundleService.class);
if (bundleService == null) {
// TODO throw exception
return installationResult
.failed("Can't check existing: BundleService not available");
}
String bundleId = this.config.getBundleId();
if (!CommonUtils.isValid(bundleId)) {
// TODO throw exception
return installationResult
.failed("Can't check existing: bundleId can not be defined");
}
// if not bundles found BundleService throws exception
try {
existingBundle = bundleService.getBundle(bundleId);
} catch (Exception e) {
// NOOP
}
if (existingBundle != null) {
installationResult.object(existingBundle);
if (this.config.isInstallOnlyIfMissing()) {
try {
if (this.config.isStartBundle())
if (existingBundle.getState() != Bundle.ACTIVE)
existingBundle.start();
} catch (BundleException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
installationResult.property(InstallationResult.PROP_BUNDLE_STATUS
, bundleStatus(existingBundle.getState()));
if (this.config.isRefresh()) {
FrameworkWiring wiring = existingBundle
.getBundleContext().getBundle(0).adapt(FrameworkWiring.class);
wiring.refreshBundles(
Arrays.asList(
new Bundle[]{existingBundle}
)
);
}
installationResult.notChanged();
} else
if (this.config.isUpdate() || this.config.isUpdateOnly()) {
try {
URI uri = URI.create(this.config.getBundleLocation());
URL url = uri.toURL();
try (InputStream is = url.openStream()) {
if (this.config.isRawUpdate()) {
existingBundle.update(is);
} else {
File file = BundleUtils.fixBundleWithUpdateLocation(is, url.toString());
try (FileInputStream fis = new FileInputStream(file)) {
existingBundle.update(fis);
} catch (BundleException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
file.delete();
}
} catch (Exception e) {
throw e;
}
if (this.config.isStartBundle())
if (existingBundle.getState() != Bundle.ACTIVE)
existingBundle.start();
installationResult.property(InstallationResult.PROP_BUNDLE_STATUS
, bundleStatus(existingBundle.getState()));
if (this.config.isRefresh()) {
FrameworkWiring wiring = existingBundle
.getBundleContext().getBundle(0).adapt(FrameworkWiring.class);
wiring.refreshBundles(
Arrays.asList(
new Bundle[]{existingBundle}
)
);
}
installationResult.updated();
} catch (MalformedURLException e) {
installationResult.error(e)
.failed("Error updating bundle: URL malformed: " + this.config.getBundleLocation());
} catch (IOException e) {
installationResult.error(e)
.failed("Error updating bundle: IOException");
} catch (BundleException e) {
installationResult.error(e)
.failed("Error updating bundle: IOException");
}
} else
if (this.config.isStartBundleOnly()) {
try {
existingBundle.start();
installationResult.started()
.property(InstallationResult.PROP_BUNDLE_STATUS
, bundleStatus(existingBundle.getState()));
} catch (Exception e) {
// TODO Auto-generated catch block
installationResult.failed().error(e);
}
} else
if (this.config.isStopBundleOnly()) {
try {
existingBundle.stop();
installationResult.stopped()
.property(InstallationResult.PROP_BUNDLE_STATUS
, bundleStatus(existingBundle.getState()));
} catch (Exception e) {
// TODO Auto-generated catch block
installationResult.failed().error(e);
}
}
return installationResult;
}
}
if (this.config.isUpdateOnly()) {
return installationResult.failed("UpdateOnly failed: bundle to update not found");
}
BundleContext bundleContext = FrameworkUtil.getBundle(ArtifactInstaller.class).getBundleContext();
try {
Bundle bundle = bundleContext.installBundle(this.config.getBundleLocation(), null);
installationResult.object(bundle);
if (this.config.getStartLevel() > 0) {
BundleStartLevel sl = bundle.adapt(BundleStartLevel.class);
sl.setStartLevel(this.config.getStartLevel());
}
if (this.config.isStartBundle()) {
bundle.start();
}
installationResult.property(InstallationResult.PROP_BUNDLE_STATUS
, bundleStatus(bundle.getState()));
} catch (BundleException e) {
installationResult.error(e)
.failed("Installing bundle failed: BundleException");
}
return installationResult.installed();
}
@Override
public InstallationResultImpl uninstall(InstallationResultImpl installationResult) {
Bundle existingBundle = null;
BundleService bundleService = OSGIUtils.getService(BundleService.class);
if (bundleService == null) {
// TODO throw exception
return installationResult
.failed("Can't check existing: BundleService not available");
}
String bundleId = this.config.getBundleId();
if (!CommonUtils.isValid(bundleId)) {
// TODO throw exception
return installationResult
.failed("Can't check existing: bundleId can not be defined");
}
// if not bundles found BundleService throws exception
try {
existingBundle = bundleService.getBundle(bundleId);
} catch (Exception e) {
// NOOP
}
if (existingBundle != null) {
try {
existingBundle.uninstall();
installationResult.uninstalled();
} catch (Exception e) {
installationResult.failed("Failed uninstalling bundle [" + bundleId + "]").error(e);
}
} else {
installationResult.notChanged().message("BUNDLE NOT FOUND");
}
return installationResult;
}
}

View File

@ -0,0 +1,26 @@
/*-
* ~~~~~~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.installer.builder.impl.local;
import ru.entaxy.platform.core.artifact.installer.builder.typed.impl.TypedInstallerHelper;
public class LocalTypedInstallerHelper extends TypedInstallerHelper {
}

View File

@ -0,0 +1,24 @@
/*-
* ~~~~~~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.installer.builder.typed;
public interface BlueprintInstaller extends CommonBundleInstaller {
}

View File

@ -0,0 +1,24 @@
/*-
* ~~~~~~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.installer.builder.typed;
public interface BundleInstaller extends CommonBundleInstaller {
}

View File

@ -0,0 +1,34 @@
/*-
* ~~~~~~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.installer.builder.typed;
public interface CommonBundleInstaller extends TypedInstaller, StartAware<CommonBundleInstaller>, StopAware<CommonBundleInstaller> {
public CommonBundleInstaller startLevel(int startLevel);
public CommonBundleInstaller installOnlyIfMissing();
public CommonBundleInstaller update();
public CommonBundleInstaller update(String symbolicName);
public CommonBundleInstaller update(String symbolicName, String version);
public CommonBundleInstaller updateOnly();
public CommonBundleInstaller rawUpdate();
public CommonBundleInstaller refresh();
}

View File

@ -0,0 +1,27 @@
/*-
* ~~~~~~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.installer.builder.typed;
public interface ConfigInstaller extends TypedInstaller {
public ConfigInstaller wrap();
public ConfigInstaller noWrap();
}

View File

@ -0,0 +1,28 @@
/*-
* ~~~~~~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.installer.builder.typed;
public interface FeaturesInstaller extends TypedInstaller, StartAware<FeaturesInstaller> {
public FeaturesInstaller installFeatures(String...features);
public FeaturesInstaller upgrade(String...features);
public FeaturesInstaller autoRefresh(boolean autoRefresh);
}

View File

@ -0,0 +1,24 @@
/*-
* ~~~~~~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.installer.builder.typed;
public interface JarInstaller extends CommonBundleInstaller {
}

View File

@ -0,0 +1,28 @@
/*-
* ~~~~~~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.installer.builder.typed;
public interface StartAware<T extends TypedInstaller> {
public T start();
public T startOnly();
public T start(boolean value);
}

View File

@ -0,0 +1,28 @@
/*-
* ~~~~~~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.installer.builder.typed;
public interface StopAware<T extends TypedInstaller> {
public T stop();
public T stopOnly();
public T stop(boolean value);
}

View File

@ -0,0 +1,26 @@
/*-
* ~~~~~~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.installer.builder.typed;
import ru.entaxy.platform.core.artifact.installer.builder.CommonInstaller;
public interface TypedInstaller extends CommonInstaller {
}

View File

@ -0,0 +1,31 @@
/*-
* ~~~~~~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.installer.builder.typed.impl;
import ru.entaxy.platform.core.artifact.installer.builder.typed.BlueprintInstaller;
public class BlueprintInstallerImpl extends CommonBundleInstallerImpl implements BlueprintInstaller {
@Override
protected String getArtifactLocation() {
return "blueprint:" + super.getArtifactLocation();
}
}

View File

@ -0,0 +1,26 @@
/*-
* ~~~~~~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.installer.builder.typed.impl;
import ru.entaxy.platform.core.artifact.installer.builder.typed.BundleInstaller;
public class BundleInstallerImpl extends CommonBundleInstallerImpl implements BundleInstaller {
}

View File

@ -0,0 +1,30 @@
/*-
* ~~~~~~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.installer.builder.typed.impl;
import ru.entaxy.platform.core.artifact.installer.builder.impl.InstallationResultImpl;
public interface CommonBundleInstallerHelper {
public void setConfig(CommonBundleInstallerHelperConfig config);
public InstallationResultImpl install(InstallationResultImpl installationResult);
public InstallationResultImpl uninstall(InstallationResultImpl installationResult);
}

View File

@ -0,0 +1,52 @@
/*-
* ~~~~~~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.installer.builder.typed.impl;
public interface CommonBundleInstallerHelperConfig {
boolean isInstallOnlyIfMissing();
String getBundleLocation();
boolean isRawUpdate();
boolean isRefresh();
boolean isUpdateOnly();
String getVersion();
String getSymbolicNameToUpdate();
boolean isUpdate();
int getStartLevel();
boolean isStartBundle();
boolean isStartBundleOnly();
boolean isStopBundle();
boolean isStopBundleOnly();
String getBundleId();
}

View File

@ -0,0 +1,302 @@
/*-
* ~~~~~~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.installer.builder.typed.impl;
import org.osgi.framework.Constants;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.core.artifact.installer.builder.InstallationResult;
import ru.entaxy.platform.core.artifact.installer.builder.impl.InstallationResultImpl;
import ru.entaxy.platform.core.artifact.installer.builder.typed.CommonBundleInstaller;
public class CommonBundleInstallerImpl extends TypedInstallerImpl
implements CommonBundleInstaller, CommonBundleInstallerHelperConfig {
protected CommonBundleInstallerHelper bundleInstallerHelper = null;
protected boolean startBundle = false;
protected boolean startBundleOnly = false;
protected boolean stopBundle = false;
protected boolean stopBundleOnly = false;
// TODO get it from framework settings
protected int startLevel = -1;
protected boolean update = false;
protected String symbolicNameToUpdate = null;
protected String version = null;
protected boolean updateOnly = false;
protected boolean refresh = false;
protected boolean rawUpdate = false;
protected boolean installOnlyIfMissing = false;
@Override
public void clearInstaller() {
super.clearInstaller();
startBundle = false;
startBundleOnly = false;
stopBundle = false;
stopBundleOnly = false;
startLevel = -1;
update = false;
symbolicNameToUpdate = null;
version = null;
updateOnly = false;
refresh = false;
rawUpdate = false;
installOnlyIfMissing = false;
}
@Override
public InstallationResult install() {
InstallationResultImpl result = InstallationResultImpl.create();
if (this.bundleInstallerHelper == null)
result.failed("HELPER NOT FOUND");
else
this.bundleInstallerHelper.install(result);
return result.property("artifact", this.artifact)
.property("bundleId", getBundleId())
.property("bundleLocation", getBundleLocation());
}
@Override
public InstallationResult uninstall() {
InstallationResultImpl result = InstallationResultImpl.create();
if (this.bundleInstallerHelper == null)
result.failed("HELPER NOT FOUND");
else
this.bundleInstallerHelper.uninstall(result);
return result.property("artifact", this.artifact)
.property("bundleId", getBundleId())
.property("bundleLocation", getBundleLocation());
}
@Override
public void setHelper(TypedInstallerHelper helper) {
super.setHelper(helper);
if (this.helper instanceof CommonBundleInstallerHelper) {
this.bundleInstallerHelper = (CommonBundleInstallerHelper)helper;
this.bundleInstallerHelper.setConfig(this);
}
}
protected String getArtifactLocation() {
return this.artifact.getLocation();
}
@Override
public CommonBundleInstaller start() {
this.stop(false);
this.stopBundleOnly = false;
return this.start(true);
}
@Override
public CommonBundleInstaller startOnly() {
this.start();
this.startBundleOnly = true;
return this;
}
@Override
public CommonBundleInstaller start(boolean value) {
this.startBundle = value;
return this;
}
@Override
public CommonBundleInstaller stop() {
this.start(false);
this.startBundleOnly = false;
return this.stop(true);
}
@Override
public CommonBundleInstaller stopOnly() {
this.stop();
this.stopBundleOnly = true;
return this;
}
@Override
public CommonBundleInstaller stop(boolean value) {
this.stopBundle = value;
return this;
}
@Override
public CommonBundleInstaller startLevel(int startLevel) {
if (startLevel > 0)
this.startLevel = startLevel;
return this;
}
@Override
public CommonBundleInstaller installOnlyIfMissing() {
this.installOnlyIfMissing = true;
return this;
}
@Override
public CommonBundleInstaller update() {
return update(null, null);
}
@Override
public CommonBundleInstaller update(String symbolicName) {
return update(symbolicName, null);
}
@Override
public CommonBundleInstaller update(String symbolicName, String version) {
this.symbolicNameToUpdate = symbolicName;
this.version = version;
this.update = true;
return this;
}
@Override
public CommonBundleInstaller updateOnly() {
this.updateOnly = true;
return this;
}
@Override
public CommonBundleInstaller refresh() {
this.refresh = true;
return this;
}
@Override
public CommonBundleInstaller rawUpdate() {
this.rawUpdate = true;
this.update = true;
return this;
}
/*
* CommonBundleInstallerHelperConfig implementation
*/
@Override
public boolean isInstallOnlyIfMissing() {
return installOnlyIfMissing;
}
@Override
public boolean isStartBundle() {
return startBundle;
}
@Override
public boolean isStartBundleOnly() {
return startBundleOnly;
}
@Override
public boolean isStopBundle() {
return stopBundle;
}
@Override
public boolean isStopBundleOnly() {
return stopBundleOnly;
}
@Override
public int getStartLevel() {
return startLevel;
}
@Override
public boolean isUpdate() {
return update;
}
@Override
public String getSymbolicNameToUpdate() {
return symbolicNameToUpdate;
}
@Override
public String getVersion() {
return version;
}
@Override
public boolean isUpdateOnly() {
return updateOnly;
}
@Override
public boolean isRefresh() {
return refresh;
}
@Override
public boolean isRawUpdate() {
return rawUpdate;
}
@Override
public String getBundleLocation() {
if (CommonUtils.isValid(sourceLocation))
return sourceLocation;
if (artifact != null)
return getArtifactLocation();
// TODO throw exception due to misconfiguration
return null;
}
@Override
public String getBundleId() {
String bundleId = "";
if (CommonUtils.isValid(bundleName)) {
bundleId += bundleName;
} else if (CommonUtils.isValid(symbolicNameToUpdate)) {
bundleId += symbolicNameToUpdate;
if (CommonUtils.isValid(version))
bundleId += version;
} else {
if (artifact != null) {
Object tmp = artifact.getArtifact().getProperties().get(Constants.BUNDLE_SYMBOLICNAME);
if (tmp != null)
if (CommonUtils.isValid(tmp.toString()))
bundleId += tmp.toString();
}
}
if (!CommonUtils.isValid(bundleId) && (artifact != null)) {
bundleId += artifact.getArtifact().getCoordinates().getGroupId()
+ "." + artifact.getArtifact().getCoordinates().getArtifactId();
}
return bundleId;
}
}

View File

@ -0,0 +1,31 @@
/*-
* ~~~~~~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.installer.builder.typed.impl;
import ru.entaxy.platform.core.artifact.installer.builder.typed.JarInstaller;
public class JarInstallerImpl extends CommonBundleInstallerImpl implements JarInstaller {
@Override
protected String getArtifactLocation() {
return "wrap:" + super.getArtifactLocation();
}
}

View File

@ -0,0 +1,24 @@
/*-
* ~~~~~~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.installer.builder.typed.impl;
public class TypedInstallerHelper {
}

View File

@ -0,0 +1,70 @@
/*-
* ~~~~~~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.installer.builder.typed.impl;
import ru.entaxy.platform.core.artifact.DeployedArtifact;
import ru.entaxy.platform.core.artifact.installer.builder.typed.TypedInstaller;
public abstract class TypedInstallerImpl implements TypedInstaller {
protected TypedInstallerHelper helper;
protected DeployedArtifact artifact;
protected String sourceLocation;
protected String bundleName;
public DeployedArtifact getArtifact() {
return artifact;
}
public void setArtifact(DeployedArtifact artifact) {
this.artifact = artifact;
}
public String getSourceLocation() {
return sourceLocation;
}
public void setSourceLocation(String sourceLocation) {
this.sourceLocation = sourceLocation;
}
public String getBundleName() {
return bundleName;
}
public void setBundleName(String bundleName) {
this.bundleName = bundleName;
}
public TypedInstallerHelper getHelper() {
return helper;
}
public void setHelper(TypedInstallerHelper helper) {
this.helper = helper;
}
public void clearInstaller() {
artifact = null;
sourceLocation = null;
bundleName = null;
}
}

View File

@ -0,0 +1,36 @@
/*-
* ~~~~~~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.installer.impl;
public abstract class AbstractArtifactInstaller {
protected ArtifactInstallerCollector collector;
public final void init() {
if (this.collector != null)
this.collector.collectInstaller(this);
}
public void setCollector(ArtifactInstallerCollector collector) {
this.collector = collector;
}
}

View File

@ -0,0 +1,26 @@
/*-
* ~~~~~~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.installer.impl;
public interface ArtifactInstallerCollector {
public void collectInstaller(AbstractArtifactInstaller installer);
}

View File

@ -0,0 +1,46 @@
/*-
* ~~~~~~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.installer.impl;
import ru.entaxy.platform.core.artifact.installer.ArtifactInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.ClusterInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.impl.cluster.DefaultCellarInstaller;
public class DefaultClusterArtifactInstaller extends AbstractArtifactInstaller
implements ArtifactInstaller<ClusterInstaller> {
protected String name = ArtifactInstaller.ARTIFACT_INSTALLER_LOCAL;
@Override
public String getName() {
return this.name;
}
@Override
public ClusterInstaller createInstaller() {
return new DefaultCellarInstaller();
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,46 @@
/*-
* ~~~~~~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.installer.impl;
import ru.entaxy.platform.core.artifact.installer.ArtifactInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.LocalInstaller;
import ru.entaxy.platform.core.artifact.installer.builder.impl.local.DefaultLocalInstaller;
public class DefaultLocalArtifactInstaller extends AbstractArtifactInstaller
implements ArtifactInstaller<LocalInstaller> {
protected String name = ArtifactInstaller.ARTIFACT_INSTALLER_LOCAL;
@Override
public String getName() {
return this.name;
}
@Override
public LocalInstaller createInstaller() {
return new DefaultLocalInstaller();
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,35 @@
/*-
* ~~~~~~licensing~~~~~~
* cellar-deployer
* ==========
* 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.legacy;
public interface BundleController {
String installAndStartBundle(String bundleUrl, String bundleName) throws Exception;
void installBundle(String bundleUrl) throws Exception;
String stopBundle(String bundleName) throws Exception;
String updateBundle(String bundleName) throws Exception;
String startBundle(String bundleName) throws Exception;
void uninstallBundle(String bundleName) throws Exception;
}

View File

@ -0,0 +1,47 @@
/*-
* ~~~~~~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.repository;
import ru.entaxy.platform.core.artifact.Artifact;
import ru.entaxy.platform.core.artifact.DeployedArtifact;
public interface ArtifactRepository {
public static final String REPO_NAME_LOCAL = "entaxy-local";
public static final String REPO_NAME_SHARED = "entaxy-shared";
public static final String REPO_NAME_UPDATES = "entaxy-updates";
public String getName();
public boolean isHealthy();
public boolean isEnabled();
public boolean isReadOnly();
public boolean isSnapshotsAllowed();
public String getUrl();
public DeployedArtifact deploy(Artifact artifact);
}

View File

@ -0,0 +1,168 @@
/*-
* ~~~~~~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.repository;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.felix.utils.properties.TypedProperties;
import org.apache.karaf.config.core.ConfigRepository;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.esb.platform.runtime.core.initializer.api.AbstractInitializer;
import ru.entaxy.esb.platform.runtime.core.initializer.api.InitializerException;
import ru.entaxy.platform.base.support.osgi.OSGIUtils;
import ru.entaxy.platform.core.artifact.service.ArtifactService;
public class ArtifactRepositoryInitializer extends AbstractInitializer {
private static final Logger log = LoggerFactory.getLogger(ArtifactRepositoryInitializer.class);
private static final String MVN_PID = "org.ops4j.pax.url.mvn";
private static final String PROP_ENTAXY_REPO_LIST = "org.ops4j.pax.url.mvn.repositories.entaxy";
private static final String ENTAXY_PROPERTY_HTTP_PORT = "entaxy.org.osgi.service.http.port";
private ArtifactService artifactService = null;
protected ConfigRepository configRepository;
@Override
public void init() throws InitializerException {
ServiceReference<?>[] references = bundleContext.getBundle().getRegisteredServices();
if (references != null)
for (int i=0; i<references.length; i++) {
Object objectClass = references[i].getProperty("objectClass");
if (objectClass!=null) {
String[] classes = (String[])objectClass;
if (Arrays.asList(classes)
.stream()
.filter((s)->ArtifactService.class.getName().equals(s))
.count() > 0) {
try {
artifactService = (ArtifactService)bundleContext.getService(references[i]);
break;
} catch (Exception e) {
log.error("Error getting ArtifactService service from ServiceReference");
}
};
};
}
if (artifactService == null)
try {
artifactService = OSGIUtils.services().ofClass(ArtifactService.class).waitService(20000).get();
} catch (Exception e) {
throw new InitializerException(this, "ArtifactService not found", "", e);
}
if (artifactService == null) {
throw new InitializerException(this, "ArtifactService not found", "", null);
}
List<String> repositoryUrls = new ArrayList<>();
String urlPrefix = "http://localhost:${" + ENTAXY_PROPERTY_HTTP_PORT + "}";
// check if 'local' and 'shared' repositories are defined
ArtifactRepository repository = artifactService.getRepository(ArtifactRepository.REPO_NAME_LOCAL);
if (!repository.isHealthy() || !repository.isEnabled()) {
// TODO create own exceptions
throw new InitializerException(this
, String.format("Repository [{}] is not healthy or not enabled", repository.getName())
, "Please check the configuration", null);
}
// don't check sha1 or md5
repositoryUrls.add(
urlPrefix + repository.getUrl()
+ "@id=" + repository.getName()
+ "@checksum=ignore"
+ (repository.isSnapshotsAllowed()?"@snapshots":"")
);
repository = artifactService.getRepository(ArtifactRepository.REPO_NAME_SHARED);
if (!repository.isHealthy() || !repository.isEnabled()) {
// TODO create own exceptions
throw new InitializerException(this
, String.format("Repository [{}] is not healthy or not enabled", repository.getName())
, "Please check the configuration", null);
}
// don't check sha1 or md5
repositoryUrls.add(
urlPrefix + repository.getUrl()
+ "@id=" + repository.getName()
+ "@checksum=ignore"
+ (repository.isSnapshotsAllowed()?"@snapshots":"")
);
// check if 'updates' repository is defined
repository = artifactService.getRepository(ArtifactRepository.REPO_NAME_UPDATES);
if (!repository.isHealthy() && repository.isEnabled()) {
// TODO create own exceptions
throw new InitializerException(this
, String.format("Repository [{}] is not healthy, but enabled", repository.getName())
, "Please check the configuration", null);
}
if (!repository.isEnabled())
log.warn("Repository [{}] is not enabled, make sure it's not done by mistake", ArtifactRepository.REPO_NAME_UPDATES);
else
repositoryUrls.add(
urlPrefix + repository.getUrl()
+ "@id=" + repository.getName()
+ (repository.isSnapshotsAllowed()?"@snapshots":"")
);
String repositoryUrlsResult = repositoryUrls.stream().collect(Collectors.joining(", "));
ServiceReference<ConfigRepository> ref1 = this.bundleContext.getServiceReference(ConfigRepository.class);
this.configRepository = this.bundleContext.getService(ref1);
try {
TypedProperties properties = this.configRepository.getConfig(MVN_PID);
properties.put(PROP_ENTAXY_REPO_LIST, repositoryUrlsResult);
this.configRepository.update(MVN_PID, properties);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidSyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void reinit() throws InitializerException {
// TODO Auto-generated method stub
}
}

View File

@ -0,0 +1,226 @@
/*-
* ~~~~~~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.repository.impl;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.util.Calendar;
import org.apache.camel.tooling.model.Strings;
import org.apache.karaf.cave.repository.Repository;
import org.apache.karaf.cave.repository.RepositoryService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.platform.core.artifact.Artifact;
import ru.entaxy.platform.core.artifact.ArtifactCoordinates;
import ru.entaxy.platform.core.artifact.DeployedArtifact;
import ru.entaxy.platform.core.artifact.repository.ArtifactRepository;
import ru.entaxy.platform.core.artifact.repository.impl.remote.RemoteRepository;
import ru.entaxy.platform.core.artifact.repository.impl.remote.RemoteRepositoryDescriptor;
import ru.entaxy.platform.core.artifact.repository.impl.remote.RemoteRepositoryFactory;
public class ArtifactRepositoryImpl implements ArtifactRepository {
private static final Logger log = LoggerFactory.getLogger(ArtifactRepositoryImpl.class);
protected boolean isHealthy = false;
protected RepositoryService repositoryService;
protected RepositoryDescriptor repositoryDescriptor;
protected RemoteRepository remoteRepository = null;
public ArtifactRepositoryImpl() {
// TODO Auto-generated constructor stub
}
public ArtifactRepositoryImpl(RepositoryDescriptor descriptor) {
this();
this.repositoryDescriptor = descriptor;
}
public void init() {
Repository caveRepo = repositoryService.repository(repositoryDescriptor.getName());
if (caveRepo == null) {
caveRepo = createRepo();
} else {
caveRepo = checkUpdateRepo(caveRepo);
}
}
protected Repository createRepo(){
Repository repo = null;
try {
repo = repositoryService.create(
repositoryDescriptor.getName(),
repositoryDescriptor.getLocation(),
Strings.isNullOrEmpty(repositoryDescriptor.getUrl())
?"/repositories/" + repositoryDescriptor.getName()
:repositoryDescriptor.getUrl(),
repositoryDescriptor.isProxy() && !Strings.isNullOrEmpty(repositoryDescriptor.getRemotes())
?repositoryDescriptor.getRemotes()
:null,
/*
repositoryDescriptor.isProxy() && !Strings.isNullOrEmpty(repositoryDescriptor.getRemotes())
&& !Strings.isNullOrEmpty(repositoryDescriptor.getLocation())
?repositoryDescriptor.isMirror()
:false*/
repositoryDescriptor.isMirror(),
"karaf",
null,
null,
null,
null,
8);
this.isHealthy = true;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
this.isHealthy = false;
}
return repo;
}
protected Repository checkUpdateRepo(Repository repo) {
try {
log.info("repositoryDescriptor.getLocation(): [{}]; repo.getLocation(): [{}]", repositoryDescriptor.getLocation(), repo.getLocation());
if (!Strings.isNullOrEmpty(repositoryDescriptor.getLocation())
&& !repo.getLocation().equalsIgnoreCase(repositoryDescriptor.getLocation()))
repositoryService.changeLocation(repositoryDescriptor.getName(), repositoryDescriptor.getLocation());
if (!repo.getUrl().equalsIgnoreCase(repositoryDescriptor.getUrl())
&& !Strings.isNullOrEmpty(repositoryDescriptor.getUrl()))
repositoryService.changeUrl(repositoryDescriptor.getName(), repositoryDescriptor.getUrl());
String repoProxy = repo.getProxy();
boolean repoIsProxy = !Strings.isNullOrEmpty(repoProxy);
if (repoIsProxy != repositoryDescriptor.isProxy()) {
if (!repositoryDescriptor.isProxy)
repositoryService.changeProxy(repositoryDescriptor.getName(), "", false);
else
repositoryService.changeProxy(repositoryDescriptor.getName()
, repositoryDescriptor.getRemotes()
, repositoryDescriptor.isMirror());
}
this.isHealthy = true;
} catch (Exception e) {
e.printStackTrace();
this.isHealthy = false;
}
return repo;
}
@Override
public DeployedArtifact deploy(Artifact artifact) {
if (isHealthy() && isEnabled() && !isReadOnly()) {
return deployArtifact(artifact);
}
return new DeployedArtifactImpl(artifact);
}
protected DeployedArtifact deployArtifact(Artifact artifact) {
String location = "mvn:";
if (!repositoryDescriptor.isProxy() || repositoryDescriptor.isMirror())
deployToCave(artifact);
if (repositoryDescriptor.isProxy())
deployToRemoteMaven(artifact);
return new DeployedArtifactImpl(artifact, location + artifact.getCoordinates().toString());
}
protected void deployToCave(Artifact artifact) {
if (artifact.getContent() != null) {
try {
ArtifactCoordinates coords = artifact.getCoordinates();
File tmpFile = File.createTempFile(getName()+"-", Calendar.getInstance().getTimeInMillis()+"");
artifact.toFile(tmpFile);
log.info("Artifact [{}] is written to [{}]", artifact.getCoordinates(), tmpFile.toURI().toURL().toString());
repositoryService.addArtifact(tmpFile.toURI().toURL().toString()
, coords.getGroupId()
, coords.getArtifactId()
, coords.getVersion()
, coords.getType()
, coords.getClassifier()
, getName());
log.info("Artifact [{}] is deployed to [{}]", artifact.getCoordinates(), getName());
// Files.deleteIfExists(tmpFil)
} catch (IOException e) {
log.error("deployToCave", e);
} catch (Exception e) {
// TODO Auto-generated catch block
log.error("deployToCave", e);
}
}
}
protected void deployToRemoteMaven(Artifact artifact) {
try {
initRemoteRepository();
this.remoteRepository.deploy(artifact);
} catch (Exception e) {
log.error("deployToRemoteMaven", e);
}
}
protected void initRemoteRepository() throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, MalformedURLException {
if (this.remoteRepository == null) {
this.remoteRepository = RemoteRepositoryFactory.create(new RemoteRepositoryDescriptor(repositoryDescriptor));
}
}
@Override
public String getName() {
return repositoryDescriptor.getName();
}
@Override
public boolean isHealthy() {
return this.isHealthy;
}
@Override
public boolean isEnabled() {
return repositoryDescriptor.isEnabled();
}
@Override
public boolean isReadOnly() {
return repositoryDescriptor.isReadOnly();
}
@Override
public boolean isSnapshotsAllowed() {
return repositoryDescriptor.isSnapshots();
}
@Override
public String getUrl() {
return repositoryService.repository(getName()).getUrl();
}
public void setRepositoryService(RepositoryService repositoryService) {
this.repositoryService = repositoryService;
}
}

View File

@ -0,0 +1,53 @@
/*-
* ~~~~~~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.repository.impl;
import ru.entaxy.platform.core.artifact.Artifact;
import ru.entaxy.platform.core.artifact.DeployedArtifact;
public class DeployedArtifactImpl implements DeployedArtifact {
protected Artifact artifact;
protected String location = null;
public DeployedArtifactImpl(Artifact artifact) {
this.artifact = artifact;
}
public DeployedArtifactImpl(Artifact artifact, String location) {
this.artifact = artifact;
this.location = location;
}
@Override
public Artifact getArtifact() {
// TODO Auto-generated method stub
return this.artifact;
}
@Override
public String getLocation() {
// TODO Auto-generated method stub
return this.location;
}
}

View File

@ -0,0 +1,52 @@
/*-
* ~~~~~~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.repository.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RepositoryConfigurableHelper extends RepositoryDescriptor {
private static final List<RepositoryConfigurableHelper> helpers = new ArrayList<>();
private static final Logger log = LoggerFactory.getLogger(RepositoryConfigurableHelper.class);
RepositoryConfigurableHelperCollector collector;
public void init() {
if (collector != null)
collector.addConfigurableHelper(this);
log.info("Helper with name [{}] created", name);
RepositoryConfigurableHelper.helpers.add(this);
log.info("Total helpers: {}:\n{}",
"" + RepositoryConfigurableHelper.helpers.size(),
RepositoryConfigurableHelper.helpers.stream()
.map((h)->h.getName()).collect(Collectors.joining("\n\t", "\t", "")));
}
public void setCollector(RepositoryConfigurableHelperCollector collector) {
this.collector = collector;
}
}

View File

@ -0,0 +1,27 @@
/*-
* ~~~~~~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.repository.impl;
/*
* Internal interface to collect helpers managed by config files
*/
public interface RepositoryConfigurableHelperCollector {
public void addConfigurableHelper(RepositoryConfigurableHelper helper);
}

View File

@ -0,0 +1,145 @@
/*-
* ~~~~~~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.repository.impl;
public class RepositoryDescriptor {
protected String name;
String location;
String url;
boolean isProxy;
boolean isMirror;
String remotes;
boolean isReadOnly = false;
boolean copyOnChange;
String username = "";
String password = "";
boolean isSnapshots = false;
boolean isEnabled = true;
String remoteHostSuffix = "";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public boolean isProxy() {
return isProxy;
}
public void setProxy(boolean isProxy) {
this.isProxy = isProxy;
}
public boolean isMirror() {
return isMirror;
}
public void setMirror(boolean isMirror) {
this.isMirror = isMirror;
}
public boolean isSnapshots() {
return isSnapshots;
}
public void setSnapshots(boolean isSnapshots) {
this.isSnapshots = isSnapshots;
}
public String getRemotes() {
return remotes;
}
public void setRemotes(String remotes) {
this.remotes = remotes;
}
public boolean isReadOnly() {
return isReadOnly;
}
public void setReadOnly(boolean isReadOnly) {
this.isReadOnly = isReadOnly;
}
public boolean isCopyOnChange() {
return copyOnChange;
}
public void setCopyOnChange(boolean copyOnChange) {
this.copyOnChange = copyOnChange;
}
public boolean isEnabled() {
return isEnabled;
}
public void setEnabled(boolean isEnabled) {
this.isEnabled = isEnabled;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRemoteHostSuffix() {
return remoteHostSuffix;
}
public void setRemoteHostSuffix(String remoteHostSuffix) {
this.remoteHostSuffix = remoteHostSuffix;
}
}

View File

@ -0,0 +1,26 @@
/*-
* ~~~~~~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.repository.impl.remote;
public abstract class AbstractRemoteRepository implements RemoteRepository {
public abstract void init(RemoteRepositoryDescriptor repositoryDescriptor);
}

View File

@ -0,0 +1,154 @@
/*-
* ~~~~~~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.repository.impl.remote;
import org.apache.http.HttpRequest;
import org.apache.http.auth.AuthenticationException;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.ssl.TrustStrategy;
import ru.entaxy.platform.base.support.CommonUtils;
import ru.entaxy.platform.core.artifact.Artifact;
import javax.net.ssl.SSLContext;
public class NexusRepository extends AbstractRemoteRepository {
private static final String DEFAULT_REPOSITORY_NAME = "entaxy";
private static final String NEXUS_ADDRESS = "/service/rest/v1";
String username;
String password;
String host;
String repositoryName;
String hostSuffix;
String apiAddress;
@Override
public void init(RemoteRepositoryDescriptor repositoryDescriptor) {
this.host = repositoryDescriptor.getHost();
String repositoryPath = repositoryDescriptor.getRepositoryPath();
if (CommonUtils.isValid(repositoryPath))
repositoryPath = repositoryPath.trim();
if (!CommonUtils.isValid(repositoryPath))
// TODO throw exception
return;
if (repositoryPath.endsWith("/"))
repositoryPath = repositoryPath.substring(0, repositoryPath.length()-1);
String[] splitted = repositoryPath.split("/");
this.repositoryName = splitted[splitted.length-1];
if (!CommonUtils.isValid(repositoryName))
this.repositoryName = DEFAULT_REPOSITORY_NAME;
this.hostSuffix = repositoryDescriptor.getHostSuffix();
this.apiAddress = this.host + this.hostSuffix + NEXUS_ADDRESS;
this.username = repositoryDescriptor.getUsername();
this.password = repositoryDescriptor.getPassword();
}
@Override
public void deploy(Artifact artifact) throws Exception {
//TODO: manage via config
TrustStrategy acceptingTrustStrategy = (cert, authType) -> true;
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext,
NoopHostnameVerifier.INSTANCE);
Registry<ConnectionSocketFactory> socketFactoryRegistry =
RegistryBuilder.<ConnectionSocketFactory> create()
.register("https", sslsf)
.register("http", new PlainConnectionSocketFactory())
.build();
BasicHttpClientConnectionManager connectionManager =
new BasicHttpClientConnectionManager(socketFactoryRegistry);
HttpPost httpPost = new HttpPost(this.apiAddress + "/components?repository=" + this.repositoryName);
addAuth(httpPost);
httpPost.setEntity(createMultipartEntityBuilder(artifact).build());
try (CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf)
.setConnectionManager(connectionManager).build();
CloseableHttpResponse response = httpClient.execute(httpPost)) {
checkAnswer(response);
}
}
private void checkAnswer(CloseableHttpResponse response) throws HttpResponseException {
if (response.getStatusLine().getStatusCode() != 204 && response.getStatusLine().getStatusCode() != 200) {
throw new HttpResponseException(response.getStatusLine().getStatusCode(),
response.getStatusLine().getReasonPhrase());
}
}
private void addAuth(HttpRequest httpRequest) throws AuthenticationException {
if (CommonUtils.isValid(username)) {
UsernamePasswordCredentials creds = new UsernamePasswordCredentials(username, password);
httpRequest.addHeader(new BasicScheme().authenticate(creds, httpRequest, null));
}
}
/*
private List getListArtifactInfo(CloseableHttpResponse response) throws IOException {
if (response.getEntity() != null && response.getEntity().getContent() != null) {
Map content = new Gson().fromJson(IOUtils.toString(response.getEntity().getContent()), Map.class);
return (List) content.get("items");
}
return null;
}
*/
private MultipartEntityBuilder createMultipartEntityBuilder(Artifact artifact) {
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody("maven2.asset1", artifact.asByteArray());
builder.addTextBody("maven2.groupId", artifact.getCoordinates().getGroupId());
builder.addTextBody("maven2.artifactId", artifact.getCoordinates().getArtifactId());
builder.addTextBody("maven2.version", artifact.getCoordinates().getVersion());
builder.addTextBody("maven2.asset1.extension", artifact.getCoordinates().getType());
builder.addTextBody("maven2.asset1.classifier", artifact.getCoordinates().getClassifier());
return builder;
}
}

View File

@ -0,0 +1,26 @@
/*-
* ~~~~~~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.repository.impl.remote;
import ru.entaxy.platform.core.artifact.Artifact;
public interface RemoteRepository {
public void deploy(Artifact artifact) throws Exception;
}

View File

@ -0,0 +1,93 @@
/*-
* ~~~~~~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.repository.impl.remote;
import java.net.MalformedURLException;
import java.net.URL;
import ru.entaxy.platform.core.artifact.repository.impl.RepositoryDescriptor;
public class RemoteRepositoryDescriptor {
String type = "nexus";
String host;
String hostSuffix;
String username;
String password;
String repositoryPath;
public RemoteRepositoryDescriptor(RepositoryDescriptor repositoryDescriptor) throws MalformedURLException {
String repositoryUrl = repositoryDescriptor.getRemotes().trim();
URL url = new URL(repositoryUrl);
this.host = url.getProtocol() + "://" + url.getHost();
if (url.getPort()>0)
this.host += ":" + url.getPort();
this.hostSuffix = repositoryDescriptor.getRemoteHostSuffix();
this.repositoryPath = url.getPath();
this.username = repositoryDescriptor.getUsername();
this.password = repositoryDescriptor.getPassword();
}
public String getType() {
return type;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRepositoryPath() {
return repositoryPath;
}
public void setRepositoryPath(String repositoryName) {
this.repositoryPath = repositoryName;
}
public String getHostSuffix() {
return hostSuffix;
}
public void setHostSuffix(String hostSuffix) {
this.hostSuffix = hostSuffix;
}
}

View File

@ -0,0 +1,49 @@
/*-
* ~~~~~~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.repository.impl.remote;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
public class RemoteRepositoryFactory {
private static Map<String, Class<? extends AbstractRemoteRepository>> repositoryClasses;
static {
repositoryClasses = new HashMap<>();
repositoryClasses.put("nexus", NexusRepository.class);
}
public static RemoteRepository create(RemoteRepositoryDescriptor descriptor)
throws NoSuchMethodException, SecurityException, InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class<? extends AbstractRemoteRepository> clazz = repositoryClasses.get(descriptor.getType());
Constructor<? extends AbstractRemoteRepository> constructor = clazz.getConstructor();
AbstractRemoteRepository remoteRepository = constructor.newInstance();
remoteRepository.init(descriptor);
return remoteRepository;
};
}

View File

@ -0,0 +1,36 @@
/*-
* ~~~~~~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.service;
import ru.entaxy.platform.core.artifact.Artifact;
import ru.entaxy.platform.core.artifact.DeployedArtifact;
import ru.entaxy.platform.core.artifact.installer.builder.InstallersWithDefaults;
import ru.entaxy.platform.core.artifact.repository.ArtifactRepository;
public interface ArtifactService {
public DeployedArtifact deployLocal(Artifact artifact);
public DeployedArtifact deployShared(Artifact artifact);
public ArtifactRepository getRepository(String name);
public InstallersWithDefaults installers();
}

View File

@ -0,0 +1,135 @@
/*-
* ~~~~~~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.service.impl;
import java.util.HashMap;
import java.util.Map;
import org.apache.karaf.cave.repository.RepositoryService;
import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.platform.core.artifact.Artifact;
import ru.entaxy.platform.core.artifact.ArtifactCoordinates;
import ru.entaxy.platform.core.artifact.DeployedArtifact;
import ru.entaxy.platform.core.artifact.installer.builder.InstallersWithDefaults;
import ru.entaxy.platform.core.artifact.installer.builder.impl.InstallersWithDefaultsImpl;
import ru.entaxy.platform.core.artifact.repository.ArtifactRepository;
import ru.entaxy.platform.core.artifact.repository.impl.ArtifactRepositoryImpl;
import ru.entaxy.platform.core.artifact.repository.impl.DeployedArtifactImpl;
import ru.entaxy.platform.core.artifact.repository.impl.RepositoryConfigurableHelper;
import ru.entaxy.platform.core.artifact.repository.impl.RepositoryConfigurableHelperCollector;
import ru.entaxy.platform.core.artifact.service.ArtifactService;
public class ArtifactServiceImpl implements ArtifactService, RepositoryConfigurableHelperCollector {
protected Map<String, ArtifactRepository> repositories = new HashMap<>();
protected BundleContext bundleContext;
protected RepositoryService repositoryService;
protected InstallersWithDefaultsImpl installers;
private final static Logger log = LoggerFactory.getLogger(ArtifactServiceImpl.class);
public ArtifactServiceImpl() {
installers = new InstallersWithDefaultsImpl();
}
public void addRepository(ArtifactRepository repository) {
}
@Override
public void addConfigurableHelper(RepositoryConfigurableHelper helper) {
log.info("Added helper for repository [{}]", helper.getName());
if (!repositories.containsKey(helper.getName())) {
ArtifactRepository repo = createRepository(helper);
this.repositories.put(repo.getName(), repo);
}
}
protected ArtifactRepository createRepository(RepositoryConfigurableHelper helper) {
ArtifactRepositoryImpl repo = new ArtifactRepositoryImpl(helper);
synchronized (repositories) {
repositories.put(repo.getName(), repo);
}
repo.setRepositoryService(repositoryService);
repo.init();
return repo;
}
@Override
public DeployedArtifact deployLocal(Artifact artifact) {
return deploy(artifact, ArtifactRepository.REPO_NAME_LOCAL);
}
@Override
public DeployedArtifact deployShared(Artifact artifact) {
return deploy(artifact, ArtifactRepository.REPO_NAME_SHARED);
}
// TODO refactor to using repository exceptions if needed
protected DeployedArtifact deploy(Artifact artifact, String repositoryName) {
String error = "Repository [" + repositoryName + "] not found";
if (repositories.containsKey(repositoryName)) {
ArtifactRepository repo = repositories.get(repositoryName);
error = String.format("Cannot deploy artifact [%s] to repository [" + repositoryName + "]", artifact.getCoordinates().toString());
if (repo.isHealthy())
if (repo.isEnabled())
if (!repo.isReadOnly())
return repo.deploy(artifact);
else
error += ": repository is readonly";
else
error += ": repository is disabled";
else
error += ": repository is not healthy";
}
log.error(error);
return new DeployedArtifactImpl(artifact);
}
@Override
public ArtifactRepository getRepository(String name) {
return this.repositories.get(name);
}
public void setBundleContext(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
public void setRepositoryService(RepositoryService repositoryService) {
this.repositoryService = repositoryService;
}
@Override
public InstallersWithDefaults installers() {
return this.installers;
}
public void setInstallers(InstallersWithDefaultsImpl installers) {
this.installers = installers;
}
}

View File

@ -0,0 +1,61 @@
###
# ~~~~~~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~~~~~~
###
##
# Local node repository
##
# Only location and snapshots are configurable, repo is always folder-based
local.location=${karaf.data}/local-repo
# set true if repo should be searched for snapshots
local.snapshots = false
##
# Shared (cluster) repository
##
# Can be folder-based or proxy for Maven repo (i.e. Nexus)
shared.location=${karaf.home}/shared-repo
# set 'true' if proxy
shared.proxy=false
# set value if proxy
shared.remotes=
# hardcoded to 'true', left for information
# shared.mirror=true
# set true if repo should be searched for snapshots
shared.snapshots = false
# credentials for upload to repository
shared.username=
shared.password=
##
# Updates (and extras) repository
##
# Can be folder-based or proxy for Maven repo (i.e. Nexus)
updates.location=
updates.proxy=true
# hardcoded to 'true', left for information
#updates.mirror=true
updates.remotes=https://nexus.entaxy.ru/nexus/repository/entaxy-public/
# set true if repo should be searched for snapshots
updates.snapshots = false
# set 'false' if not used
updates.enabled=true

View File

@ -0,0 +1,144 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~~~~~~licensing~~~~~~
uniform-service-exchange-endpoint
==========
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~~~~~~
-->
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.4.0"
xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.6.0"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
">
<!-- allow the use of system properties -->
<ext:property-placeholder placeholder-prefix="$[" placeholder-suffix="]" />
<cm:property-placeholder persistent-id="ru.entaxy.esb.artifact.repositories" update-strategy="reload">
<cm:default-properties>
<!-- local repository -->
<cm:property name="local.location" value="$[karaf.data]/local-repo"/>
<cm:property name="local.snapshots" value="false"/>
<!-- shared repository -->
<cm:property name="shared.location" value="$[karaf.home]/shared-repo"/>
<cm:property name="shared.proxy" value="false"/>
<cm:property name="shared.mirror" value="true"/>
<cm:property name="shared.snapshots" value="false"/>
<cm:property name="shared.remotes" value=""/>
<cm:property name="shared.remotes.hostSuffix" value=""/>
<cm:property name="shared.username" value=""/>
<cm:property name="shared.password" value=""/>
<!-- update repository -->
<cm:property name="updates.location" value=""/>
<cm:property name="updates.proxy" value="true"/>
<cm:property name="updates.mirror" value="true"/>
<cm:property name="updates.enabled" value="true"/>
<cm:property name="updates.remotes.hostSuffix" value=""/>
<cm:property name="updates.snapshots" value="false"/>
<cm:property name="updates.remotes" value="https://nexus.entaxy.ru/nexus/repository/entaxy-public/"/>
</cm:default-properties>
</cm:property-placeholder>
<cm:property-placeholder persistent-id="ru.entaxy.esb.artifact.installer" update-strategy="reload"
placeholder-prefix="$((" placeholder-suffix="))" >
<cm:default-properties>
<cm:property name="installers.localOnlyMode" value="false"/>
</cm:default-properties>
</cm:property-placeholder>
<reference id="repositoryService" availability="mandatory" interface="org.apache.karaf.cave.repository.RepositoryService">
</reference>
<bean id="artifactServiceImpl" class="ru.entaxy.platform.core.artifact.service.impl.ArtifactServiceImpl" activation="eager">
<property name="bundleContext" ref="blueprintBundleContext"></property>
<property name="repositoryService" ref="repositoryService"></property>
<property name="installers" ref="installers"></property>
</bean>
<service interface="ru.entaxy.platform.core.artifact.service.ArtifactService" activation="eager" ref="artifactServiceImpl">
</service>
<!-- cm:managed-service-factory factory-pid="ru.entaxy.platform.artifact.repository" interface="java.lang.Object">
<cm:managed-component class="ru.entaxy.platform.core.artifact.repository.impl.RepositoryConfigurableHelper"
init-method="init">
<cm:managed-properties persistent-id="" update-strategy="container-managed" />
<property name="name" value="unset-name"></property>
<property name="collector" ref="artifactServiceImpl"></property>
</cm:managed-component>
</cm:managed-service-factory-->
<bean id="repoHelperLocal" init-method="init"
class="ru.entaxy.platform.core.artifact.repository.impl.RepositoryConfigurableHelper">
<property name="name" value="entaxy-local"></property>
<property name="location" value="${local.location}"></property>
<property name="snapshots" value="${local.snapshots}"></property>
<property name="collector" ref="artifactServiceImpl"></property>
</bean>
<bean id="repoHelperShared" init-method="init"
class="ru.entaxy.platform.core.artifact.repository.impl.RepositoryConfigurableHelper">
<property name="name" value="entaxy-shared"></property>
<property name="location" value="${shared.location}"></property>
<property name="proxy" value="${shared.proxy}"></property>
<!-- property name="mirror" value="${shared.mirror}"></property -->
<property name="mirror" value="true"></property>
<property name="snapshots" value="${shared.snapshots}"></property>
<property name="remotes" value="${shared.remotes}"></property>
<property name="remoteHostSuffix" value="${shared.remotes.hostSuffix}"></property>
<property name="username" value="${shared.username}"></property>
<property name="password" value="${shared.password}"></property>
<property name="collector" ref="artifactServiceImpl"></property>
</bean>
<bean id="repoHelperUpdate" init-method="init"
class="ru.entaxy.platform.core.artifact.repository.impl.RepositoryConfigurableHelper">
<property name="name" value="entaxy-updates"></property>
<property name="readOnly" value="true"></property>
<property name="location" value="${updates.location}"></property>
<property name="proxy" value="${updates.proxy}"></property>
<!-- property name="mirror" value="${updates.mirror}"></property -->
<property name="mirror" value="true"></property>
<property name="snapshots" value="${updates.snapshots}"></property>
<property name="remotes" value="${updates.remotes}"></property>
<property name="remoteHostSuffix" value="${updates.remotes.hostSuffix}"></property>
<property name="collector" ref="artifactServiceImpl"></property>
</bean>
<bean id="defaultLocalInstaller" class="ru.entaxy.platform.core.artifact.installer.impl.DefaultLocalArtifactInstaller">
</bean>
<bean id="defaultClusterInstaller" class="ru.entaxy.platform.core.artifact.installer.impl.DefaultClusterArtifactInstaller">
</bean>
<bean id="defaultInstallers" class="ru.entaxy.platform.core.artifact.installer.builder.impl.InstallersImpl">
<property name="local" ref="defaultLocalInstaller"></property>
<property name="cluster" ref="defaultClusterInstaller"></property>
<property name="localOnlyMode" value="$((installers.localOnlyMode))"></property>
</bean>
<bean id="installers" class="ru.entaxy.platform.core.artifact.installer.builder.impl.InstallersWithDefaultsImpl">
<property name="defaults" ref="defaultInstallers"></property>
<property name="localOnlyMode" value="$((installers.localOnlyMode))"></property>
</bean>
</blueprint>

View File

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

View File

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

View File

@ -0,0 +1,113 @@
<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>cluster</artifactId>
<version>1.8.1</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core.cluster</groupId>
<artifactId>cluster-persistence-service</artifactId>
<packaging>bundle</packaging>
<name>ENTAXY :: PLATFORM :: CORE :: CLUSTER :: PERSISTENCE</name>
<description>ENTAXY :: PLATFORM :: CORE :: CLUSTER :: PERSISTENCE</description>
<properties>
<bundle.osgi.private.pkg>
ru.entaxy.esb.platform.core.cluster.persistence.activator,
ru.entaxy.esb.platform.core.cluster.persistence.handler
</bundle.osgi.private.pkg>
<bundle.osgi.import.pkg>
!org.apache.karaf.cellar.bundle.shell*,
org.osgi.framework,
*
</bundle.osgi.import.pkg>
<bundle.osgi.export.pkg>
ru.entaxy.esb.platform.core.cluster.persistence
</bundle.osgi.export.pkg>
<bundle.osgi.dynamicimport.pkg>
*
</bundle.osgi.dynamicimport.pkg>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.karaf.features</groupId>
<artifactId>org.apache.karaf.features.core</artifactId>
<version>${karaf.version}</version>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
<version>${osgi.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.karaf</groupId>
<artifactId>org.apache.karaf.util</artifactId>
<version>${karaf.version}</version>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.compendium</artifactId>
<version>${osgi.compendium.version}</version>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-all</artifactId>
<version>${hazelcast.version}</version>
</dependency>
<dependency>
<groupId>org.apache.karaf.cellar</groupId>
<artifactId>org.apache.karaf.cellar.core</artifactId>
<version>${cellar.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.karaf</groupId>
<artifactId>org.apache.karaf.util</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.karaf.cellar</groupId>
<artifactId>org.apache.karaf.cellar.bundle</artifactId>
<version>${cellar.version}-ENTAXY</version>
<exclusions>
<exclusion>
<groupId>org.apache.karaf</groupId>
<artifactId>org.apache.karaf.util</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.karaf.cellar</groupId>
<artifactId>org.apache.karaf.cellar.hazelcast</artifactId>
<version>${cellar.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.karaf.tooling</groupId>
<artifactId>karaf-services-maven-plugin</artifactId>
<version>${karaf.version}</version>
<executions>
<execution>
<id>service-metadata-generate</id>
<phase>process-classes</phase>
<goals>
<goal>service-metadata-generate</goal>
</goals>
<configuration>
<artifactInclude>.*</artifactInclude>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,146 @@
/*-
* ~~~~~~licensing~~~~~~
* cluster-persistence-service
* ==========
* 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.esb.platform.core.cluster.persistence;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.karaf.cellar.bundle.BundleState;
import org.apache.karaf.cellar.core.ClusterManager;
import org.apache.karaf.cellar.core.Configurations;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Helper<T> {
private static final Logger log = LoggerFactory.getLogger(Helper.class);
public static final String DELIMITER = "~~_DEL_~~";
public static final String SEPARATOR = "~~_SEP_~~";
protected String mapBaseName;
protected String classifier;
protected Class<T> dataClass;
protected Serializer<T> serializer;
protected String rootPath;
protected String subPath;
protected ServiceProvider serviceProvider;
public Helper(ServiceProvider serviceProvider, String mapBaseName, String classifier, Class<T> dataClass) {
this.serviceProvider = serviceProvider;
this.mapBaseName = mapBaseName;
this.classifier = classifier;
this.dataClass = dataClass;
this.serializer = new Serializer<>(this.dataClass);
this.rootPath = System.getProperty("karaf.home");
this.subPath = "cluster-state";
}
protected Path getTargetPath(String groupName) {
String fileName = "cluster." + classifier + "." + groupName + ".state";
Path p = Paths.get(this.rootPath, this.subPath, fileName);
return p;
}
public void saveClusterState(String groupName) {
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(this.dataClass.getClassLoader());
if (!checkGroup(groupName))
return;
ClusterManager clusterManager = this.serviceProvider.getClusterManager();
@SuppressWarnings("unchecked")
Map<String, T> clusterData = clusterManager.getMap(this.mapBaseName + Configurations.SEPARATOR + groupName);
String serialized = "";
serialized = clusterData.entrySet().stream()
.<String>map((entry)->{return entry.getKey() + DELIMITER + serializer.toString(entry.getValue());})
.collect(Collectors.joining(SEPARATOR));
Path p = getTargetPath(groupName);
try {
// if (!p.toFile().exists())
// p.toFile().createNewFile();
Files.createDirectories(p.getParent());
Files.write(p, serialized.getBytes());
} catch (IOException e) {
log.error("FAILED saving state to [" + p.toUri().toString() + "]", e);
}
Thread.currentThread().setContextClassLoader(originalClassLoader);
}
public void loadClusterState(String groupName) {
ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(this.dataClass.getClassLoader());
if (!checkGroup(groupName))
return;
Path p = getTargetPath(groupName);
if (!p.toFile().exists()) {
log.info("File [{}] doesn't exist, skip loading [{}] from [{}]"
, p.toUri().toString()
, this.classifier
, this.mapBaseName);
return;
}
String data = "";
try {
data = Files.readString(p);
} catch (IOException e) {
log.error("Error reading data from [" + p.toUri().toString() + "]", e);
}
if ((data == null) || data.length()==0 )
return;
ClusterManager clusterManager = this.serviceProvider.getClusterManager();
@SuppressWarnings("unchecked")
Map<String, T> clusterData = clusterManager.getMap(this.mapBaseName + Configurations.SEPARATOR + groupName);
String[] entries = data.split(SEPARATOR);
for (int i=0; i<entries.length; i++) {
String[] entry = entries[i].split(DELIMITER);
T object = serializer.fromString(entry[1]);
clusterData.put(entry[0], object);
}
Thread.currentThread().setContextClassLoader(originalClassLoader);
}
protected boolean checkGroup(String groupName) {
// TODO implement check
return true;
}
}

View File

@ -0,0 +1,162 @@
/*-
* ~~~~~~licensing~~~~~~
* cluster-persistence-service
* ==========
* 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.esb.platform.core.cluster.persistence;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PersistenceManager<T> {
private static final Logger log = LoggerFactory.getLogger(PersistenceManager.class);
private static class UpdateMarker {
private boolean updated = false;
public void update() {
this.updated = true;
}
public void clear() {
this.updated = false;
}
public boolean isUpdated() {
return updated;
}
}
private static interface UpdateTaskCallback {
public void executed();
}
private class Executor implements UpdateTaskCallback {
private Boolean isRunning = false;
private ExecutorService threadPool = Executors.newSingleThreadExecutor();
public synchronized void run() {
synchronized (isRunning) {
if (this.isRunning)
return;
this.isRunning = true;
log.info("~~> EXECUTOR :: RUN");
UpdateTask ut = new UpdateTask(PersistenceManager.this.helper, this);
PersistenceManager.this.clear();
threadPool.execute(ut);
}
}
@Override
public synchronized void executed() {
log.info("~~> EXECUTOR :: EXECUTED");
synchronized (isRunning) {
this.isRunning = false;
}
PersistenceManager.this.executed();
}
}
private static class UpdateTask implements Runnable {
private Helper<?> helper;
private UpdateTaskCallback callback;
public UpdateTask(Helper<?> helper, UpdateTaskCallback callback) {
this.helper = helper;
this.callback = callback;
}
@Override
public void run() {
log.debug("~~> UPDATE_TASK :: RUN");
try {
log.debug("~~> UPDATE_TASK :: RUN :: sleeping");
Thread.currentThread().sleep(15000);
log.debug("~~> UPDATE_TASK :: RUN :: processig");
// TODO add support for different groups
this.helper.saveClusterState("default");
log.debug("~~> UPDATE_TASK :: RUN :: processed");
this.callback.executed();
} catch (InterruptedException e) {
log.error("UpdateTask", e);
}
}
}
private final UpdateMarker marker = new UpdateMarker();
private Helper<T> helper;
private Executor executor = new Executor();
public PersistenceManager(ServiceProvider serviceProvider, String mapBaseName, String classifier, Class<T> dataClass) {
helper = new Helper<>(serviceProvider, mapBaseName, classifier, dataClass);
}
public void restore() {
// this is called only once before the consumer started
// so we can call helper directly
helper.loadClusterState("default");
}
public void persist() {
this.updated();
}
protected void runExecutor() {
synchronized (executor) {
if (!executor.isRunning)
executor.run();
}
}
public void updated() {
log.info("~~> UPDATED");
synchronized (marker) {
marker.update();
}
runExecutor();
}
protected synchronized void clear() {
synchronized (marker) {
marker.clear();
}
}
protected synchronized void executed() {
boolean updated = false;
synchronized (marker) {
updated = marker.isUpdated();
}
if (updated)
runExecutor();
}
}

View File

@ -0,0 +1,75 @@
/*-
* ~~~~~~licensing~~~~~~
* cluster-persistence-service
* ==========
* 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.esb.platform.core.cluster.persistence;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Serializer<T> {
private static final Logger log = LoggerFactory.getLogger(Serializer.class);
private Class<T> dataClass;
public Serializer(Class<T> clazz) {
this.dataClass = clazz;
}
public String toString(T object) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos;
try {
oos = new ObjectOutputStream( baos );
oos.writeObject((Serializable) object);
oos.close();
} catch (IOException e) {
log.error("Serializer.toString", e);
}
return Base64.getEncoder().encodeToString(baos.toByteArray());
}
public T fromString(String str) {
byte [] data = Base64.getDecoder().decode(str);
// ClassLoader original = Thread.currentThread().getContextClassLoader();
// Thread.currentThread().setContextClassLoader(dataClass.getClassLoader());
T result = null;
try {
ObjectInputStream ois = new ObjectInputStream(
new ByteArrayInputStream( data ) );
Object o = ois.readObject();
ois.close();
result = dataClass.cast(o);
} catch (Exception e) {
result = null;
}
// Thread.currentThread().setContextClassLoader(original);
return result;
}
}

View File

@ -0,0 +1,30 @@
/*-
* ~~~~~~licensing~~~~~~
* cluster-persistence-service
* ==========
* 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.esb.platform.core.cluster.persistence;
import org.apache.karaf.cellar.core.ClusterManager;
import org.apache.karaf.cellar.core.GroupManager;
public interface ServiceProvider {
public ClusterManager getClusterManager();
public GroupManager getGroupManager();
}

View File

@ -0,0 +1,228 @@
/*-
* ~~~~~~licensing~~~~~~
* hazelcast-test
* ==========
* 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.esb.platform.core.cluster.persistence.activator;
import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.karaf.cellar.bundle.BundleState;
import org.apache.karaf.cellar.bundle.Constants;
import org.apache.karaf.cellar.bundle.management.CellarBundleMBean;
import org.apache.karaf.cellar.core.ClusterManager;
import org.apache.karaf.cellar.core.GroupManager;
import org.apache.karaf.cellar.core.event.EventHandler;
import org.apache.karaf.features.FeaturesService;
import org.apache.karaf.util.tracker.BaseActivator;
import org.apache.karaf.util.tracker.annotation.ProvideService;
import org.apache.karaf.util.tracker.annotation.RequireService;
import org.apache.karaf.util.tracker.annotation.Services;
import org.osgi.service.cm.ConfigurationAdmin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.Member;
import com.hazelcast.core.MemberAttributeEvent;
import com.hazelcast.core.MembershipEvent;
import com.hazelcast.core.MembershipListener;
import ru.entaxy.esb.platform.core.cluster.persistence.PersistenceManager;
import ru.entaxy.esb.platform.core.cluster.persistence.ServiceProvider;
import ru.entaxy.esb.platform.core.cluster.persistence.handler.LocalBundleEventHandler;
import ru.entaxy.esb.platform.core.cluster.persistence.handler.LocalEventHandlerRegistryDispatcher;
import ru.entaxy.esb.platform.core.cluster.persistence.handler.LocalHandlerRegistry;
import ru.entaxy.esb.platform.core.cluster.persistence.handler.LocalTopicConsumer;
@Services(requires = {
@RequireService(ClusterManager.class),
@RequireService(GroupManager.class),
@RequireService(CellarBundleMBean.class),
@RequireService(ConfigurationAdmin.class),
@RequireService(FeaturesService.class),
@RequireService(HazelcastInstance.class)
},
provides = {
@ProvideService(EventHandler.class)
}
)
public class Activator extends BaseActivator implements ServiceProvider, MembershipListener {
private static final String CLASSIFIER_BUNDLE = "bundle";
private static final Logger log = LoggerFactory.getLogger(BaseActivator.class);
private LocalBundleEventHandler bundleEventHandler;
private LocalTopicConsumer consumer;
private LocalEventHandlerRegistryDispatcher dispatcher;
private LocalHandlerRegistry handlerRegistry;
private ClusterManager clusterManager;
private GroupManager groupManager;
private HazelcastInstance hazelcastInstance;
private Map<String, PersistenceManager> managers = new ConcurrentHashMap<>();
@Override
protected void doStart() throws Exception {
clusterManager = getTrackedService(ClusterManager.class);
if (clusterManager == null)
return;
groupManager = getTrackedService(GroupManager.class);
if (groupManager == null)
return;
ConfigurationAdmin configurationAdmin = getTrackedService(ConfigurationAdmin.class);
if (configurationAdmin == null)
return;
FeaturesService featuresService = getTrackedService(FeaturesService.class);
if (featuresService == null)
return;
hazelcastInstance = getTrackedService(HazelcastInstance.class);
if (hazelcastInstance == null)
return;
handlerRegistry = new LocalHandlerRegistry<>();
/*
* bundle management
*/
PersistenceManager<BundleState> bundlePersistenceManager = new PersistenceManager<>(this
, Constants.BUNDLE_MAP
, CLASSIFIER_BUNDLE
, BundleState.class);
this.managers.put(CLASSIFIER_BUNDLE, bundlePersistenceManager);
bundleEventHandler = new LocalBundleEventHandler();
bundleEventHandler.setConfigurationAdmin(configurationAdmin);
bundleEventHandler.setClusterManager(clusterManager);
bundleEventHandler.setGroupManager(groupManager);
bundleEventHandler.setBundleContext(bundleContext);
bundleEventHandler.setFeaturesService(featuresService);
bundleEventHandler.setPersistenceManager(bundlePersistenceManager);
bundleEventHandler.init();
handlerRegistry.addHandler(bundleEventHandler);
/*
* feature management
*/
// TODO
/*
* kar management
*/
// TODO
/*
* common services
*/
dispatcher = new LocalEventHandlerRegistryDispatcher<>();
dispatcher.setHandlerRegistry(handlerRegistry);
dispatcher.init();
consumer = new LocalTopicConsumer();
consumer.setInstance(hazelcastInstance);
consumer.setDispatcher(dispatcher);
consumer.setNode(clusterManager.getNode());
consumer.setConfigurationAdmin(configurationAdmin);
consumer.init();
if (iAmAlone()) {
restoreAll();
consumer.start();
}
hazelcastInstance.getCluster().addMembershipListener(this);
}
protected void checkStartStopConsumer() {
if (iAmAlone())
consumer.start();
else
consumer.stop();
}
protected void restoreAll() {
for (PersistenceManager pm: managers.values())
pm.restore();
}
protected void persistAll() {
for (PersistenceManager pm: managers.values())
pm.persist();
}
protected boolean iAmAlone() {
if (hazelcastInstance.getCluster().getMembers().size()>1)
return false;
return true;
}
@Override
protected void doStop() {
// TODO Auto-generated method stub
super.doStop();
}
@Override
public ClusterManager getClusterManager() {
return clusterManager;
}
@Override
public GroupManager getGroupManager() {
return groupManager;
}
@Override
public void memberAdded(MembershipEvent membershipEvent) {
Member member = membershipEvent.getMember();
Member local = hazelcastInstance.getCluster().getLocalMember();
checkStartStopConsumer();
}
@Override
public void memberAttributeChanged(MemberAttributeEvent event) {
// TODO Auto-generated method stub
}
@Override
public void memberRemoved(MembershipEvent membershipEvent) {
Member member = membershipEvent.getMember();
Member local = hazelcastInstance.getCluster().getLocalMember();
if (member.equals(local))
consumer.stop();
else if (iAmAlone()) {
// all other nodes gone
persistAll();
consumer.start();
}
}
}

View File

@ -0,0 +1,177 @@
/*-
* ~~~~~~licensing~~~~~~
* cluster-persistence-service
* ==========
* 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~~~~~~
*/
/*
* 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.
*/
package ru.entaxy.esb.platform.core.cluster.persistence.handler;
import org.apache.karaf.cellar.bundle.BundleEventHandler;
import org.apache.karaf.cellar.bundle.BundleState;
import org.apache.karaf.cellar.bundle.BundleSupport;
import org.apache.karaf.cellar.bundle.ClusterBundleEvent;
import org.apache.karaf.cellar.bundle.Constants;
import org.apache.karaf.cellar.core.Configurations;
import org.apache.karaf.cellar.core.control.BasicSwitch;
import org.apache.karaf.cellar.core.control.Switch;
import org.apache.karaf.cellar.core.control.SwitchStatus;
import org.apache.karaf.cellar.core.event.EventHandler;
import org.apache.karaf.cellar.core.event.EventType;
import org.apache.karaf.features.Feature;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.wiring.FrameworkWiring;
import org.osgi.service.cm.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.esb.platform.core.cluster.persistence.PersistenceManager;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* The BundleEventHandler is responsible to process received cluster event for bundles.
*/
public class LocalBundleEventHandler extends BundleSupport implements EventHandler<ClusterBundleEvent> {
private static final transient Logger log = LoggerFactory.getLogger(LocalBundleEventHandler.class);
public static final String SWITCH_ID = "org.apache.karaf.cellar.bundle.handler";
private final Switch eventSwitch = new BasicSwitch(SWITCH_ID);
private PersistenceManager persistenceManager;
/**
* Handle received bundle cluster events.
*
* @param event the received bundle cluster event.
*/
@Override
public void handle(ClusterBundleEvent event) {
// check if the handler switch is ON
if (this.getSwitch().getStatus().equals(SwitchStatus.OFF)) {
log.debug("CELLAR BUNDLE: {} switch is OFF, cluster event is not handled", SWITCH_ID);
return;
}
if (groupManager == null) {
//in rare cases for example right after installation this happens!
log.error("CELLAR BUNDLE: retrieved event {} while groupManager is not available yet!", event);
return;
}
// check if the group is local
if (!groupManager.isLocalGroup(event.getSourceGroup().getName())) {
log.debug("CELLAR BUNDLE: node is not part of the event cluster group {}", event.getSourceGroup().getName());
return;
}
try {
// check if it's not a "local" event
if (event.getLocal() != null && event.getLocal().getId().equalsIgnoreCase(clusterManager.getNode().getId())) {
log.trace("CELLAR BUNDLE: cluster event is local (coming from local synchronizer or listener)");
return;
}
// check if the pid is marked as local.
if (isAllowed(event.getSourceGroup(), Constants.CATEGORY, event.getLocation(), EventType.INBOUND)) {
// check the features first
List<Feature> matchingFeatures = retrieveFeature(event.getLocation());
for (Feature feature : matchingFeatures) {
if (!isAllowed(event.getSourceGroup(), "feature", feature.getName(), EventType.INBOUND)) {
log.trace("CELLAR BUNDLE: bundle {} is contained in feature {} marked BLOCKED INBOUND for cluster group {}", event.getLocation(), feature.getName(), event.getSourceGroup().getName());
return;
}
}
// TODO mark cluster state as needed to be saved
log.info("-->> WE NEED TO SAVE CLUSTER STATE");
this.persistenceManager.updated();
} else
log.trace("CELLAR BUNDLE: bundle {} is marked BLOCKED INBOUND for cluster group {}", event.getSymbolicName(), event.getSourceGroup().getName());
} catch (BundleException e) {
log.error("CELLAR BUNDLE: failed to install bundle {}/{}.", new Object[]{event.getSymbolicName(), event.getVersion()}, e);
} catch (Exception e) {
log.error("CELLAR BUNDLE: failed to handle bundle event", e);
}
}
public void init() {
// nothing to do
}
public void destroy() {
// nothing to do
}
/**
* Get the cluster bundle event handler switch.
*
* @return the cluster bundle event handler switch.
*/
@Override
public Switch getSwitch() {
// load the switch status from the config
try {
Configuration configuration = configurationAdmin.getConfiguration(Configurations.NODE, null);
if (configuration != null) {
Boolean status = new Boolean((String) configuration.getProperties().get(Configurations.HANDLER
+ "."
+ BundleEventHandler.class.getName()));
if (status) {
eventSwitch.turnOn();
} else {
eventSwitch.turnOff();
}
}
} catch (Exception e) {
// ignore
}
return eventSwitch;
}
public void setPersistenceManager(PersistenceManager persistenceManager) {
this.persistenceManager = persistenceManager;
}
/**
* Get the cluster event type.
*
* @return the cluster bundle event type.
*/
@Override
public Class<ClusterBundleEvent> getType() {
return ClusterBundleEvent.class;
}
}

View File

@ -0,0 +1,123 @@
/*-
* ~~~~~~licensing~~~~~~
* cluster-persistence-service
* ==========
* 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~~~~~~
*/
/*
* 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.
*/
package ru.entaxy.esb.platform.core.cluster.persistence.handler;
import org.apache.karaf.cellar.core.event.Event;
import org.apache.karaf.cellar.core.event.EventHandler;
import org.apache.karaf.cellar.core.event.EventHandlerRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Event dispatcher task.
*/
public class LocalEventDispatchTask<E extends Event> implements Runnable {
private static final transient Logger LOGGER = LoggerFactory.getLogger(LocalEventDispatchTask.class);
private static final long DEFAULT_TIMEOUT = 30000;
private E event;
private EventHandlerRegistry handlerRegistry;
private long timeout;
private long interval = 1000;
public LocalEventDispatchTask(E event, EventHandlerRegistry handlerRegistry) {
this.event = event;
this.handlerRegistry = handlerRegistry;
if (System.getProperty("cellar.timeout") != null) {
try {
this.timeout = Long.parseLong(System.getProperty("cellar.timeout"));
} catch (Exception e) {
this.timeout = DEFAULT_TIMEOUT;
}
} else {
this.timeout = DEFAULT_TIMEOUT;
}
}
public LocalEventDispatchTask(E event, EventHandlerRegistry handlerRegistry, long timeout) {
this.event = event;
this.handlerRegistry = handlerRegistry;
this.timeout = timeout;
}
public LocalEventDispatchTask(EventHandlerRegistry handlerRegistry, long timeout, long interval, E event) {
this.handlerRegistry = handlerRegistry;
this.timeout = timeout;
this.interval = interval;
this.event = event;
}
@Override
public void run() {
try {
boolean dispatched = false;
for (long delay = 0; delay < timeout && !dispatched; delay += interval) {
EventHandler handler = handlerRegistry.getHandler(event);
if (handler != null) {
handler.handle(event);
dispatched = true;
} else {
try {
Thread.sleep(interval);
} catch (InterruptedException e) {
LOGGER.warn("Interrupted while waiting for cluster event handler", e);
}
}
}
if (!dispatched) {
LOGGER.warn("Failed to retrieve handler for cluster event {}", event.getClass());
}
} catch (Exception ex) {
LOGGER.error("Error while dispatching task", ex);
}
}
public long getTimeout() {
return timeout;
}
public void setTimeout(long timeout) {
this.timeout = timeout;
}
public long getInterval() {
return interval;
}
public void setInterval(long interval) {
this.interval = interval;
}
}

View File

@ -0,0 +1,97 @@
/*-
* ~~~~~~licensing~~~~~~
* cluster-persistence-service
* ==========
* 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~~~~~~
*/
/*
* 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.
*/
package ru.entaxy.esb.platform.core.cluster.persistence.handler;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.karaf.cellar.core.event.Event;
import org.apache.karaf.cellar.core.event.EventDispatcher;
import org.apache.karaf.cellar.core.event.EventHandlerRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Event handler service registry dispatcher.
*/
public class LocalEventHandlerRegistryDispatcher<E extends Event> implements EventDispatcher<E> {
private static final transient Logger LOGGER = LoggerFactory.getLogger(LocalEventHandlerRegistryDispatcher.class);
private ExecutorService threadPool;
private EventHandlerRegistry handlerRegistry;
public void init() {
if (threadPool == null) {
if (Boolean.getBoolean(this.getClass().getName() + ".threadPool.singleThreadExecutor")) {
LOGGER.info("Will use an Executor that uses a single worker thread");
threadPool = Executors.newSingleThreadExecutor();
} else {
LOGGER.info("Will use an Executor with a pool of threads");
threadPool = Executors.newCachedThreadPool();
}
}
}
/**
* Dispatch a cluster {@code Event} to the appropriate cluster {@code EventHandler}.
*
* @param event the cluster event to dispatch.
*/
public void dispatch(E event) {
LocalEventDispatchTask task = new LocalEventDispatchTask(event, handlerRegistry);
threadPool.execute(task);
}
public EventHandlerRegistry getHandlerRegistry() {
return handlerRegistry;
}
public void setHandlerRegistry(EventHandlerRegistry handlerRegistry) {
this.handlerRegistry = handlerRegistry;
}
public ExecutorService getThreadPool() {
return threadPool;
}
public void setThreadPool(ExecutorService threadPool) {
this.threadPool = threadPool;
}
public void destroy() {
if (threadPool != null) {
threadPool.shutdown();
}
}
}

View File

@ -0,0 +1,42 @@
/*-
* ~~~~~~licensing~~~~~~
* cluster-persistence-service
* ==========
* 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.esb.platform.core.cluster.persistence.handler;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.karaf.cellar.core.event.Event;
import org.apache.karaf.cellar.core.event.EventHandler;
import org.apache.karaf.cellar.core.event.EventHandlerRegistry;
public class LocalHandlerRegistry<E extends Event> implements EventHandlerRegistry<E> {
private Map<Class,EventHandler> eventHandlerMap = new ConcurrentHashMap<Class,EventHandler>();
@Override
public EventHandler<E> getHandler(E event) {
return eventHandlerMap.get(event.getClass());
}
public void addHandler(EventHandler eventHandler) {
eventHandlerMap.put(eventHandler.getType(), eventHandler);
}
}

View File

@ -0,0 +1,185 @@
/*-
* ~~~~~~licensing~~~~~~
* cluster-persistence-service
* ==========
* 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~~~~~~
*/
/*
* 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.
*/
package ru.entaxy.esb.platform.core.cluster.persistence.handler;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.ITopic;
import com.hazelcast.core.Message;
import com.hazelcast.core.MessageListener;
import org.apache.karaf.cellar.core.Configurations;
import org.apache.karaf.cellar.core.Dispatcher;
import org.apache.karaf.cellar.core.Node;
import org.apache.karaf.cellar.core.control.BasicSwitch;
import org.apache.karaf.cellar.core.control.Switch;
import org.apache.karaf.cellar.core.control.SwitchStatus;
import org.apache.karaf.cellar.core.event.Event;
import org.apache.karaf.cellar.core.event.EventConsumer;
import org.apache.karaf.cellar.hazelcast.Constants;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Consumes messages from the Hazelcast {@code ITopic} and calls the {@code EventDispatcher}.
*/
public class LocalTopicConsumer<E extends Event> implements EventConsumer<E>, MessageListener<E> {
private static final transient Logger log = LoggerFactory.getLogger(LocalTopicConsumer.class);
public static final String SWITCH_ID = "org.apache.karaf.cellar.topic.consumer";
private final Switch eventSwitch = new BasicSwitch(SWITCH_ID);
private String registrationId;
private HazelcastInstance instance;
private ITopic topic;
private Dispatcher dispatcher;
private Node node;
private ConfigurationAdmin configurationAdmin;
private boolean isConsuming;
public void init() {
if (topic == null) {
topic = instance.getTopic(Constants.TOPIC);
}
}
public void destroy() {
stop();
}
@Override
public void consume(E event) {
// check if event has a specified destination.
if ((event.getDestination() == null || event.getDestination().contains(node)) && (this.getSwitch().getStatus().equals(SwitchStatus.ON) || event.getForce())) {
log.info("==>> EVENT TO PROCESS");
dispatcher.dispatch(event);
} else {
if (eventSwitch.getStatus().equals(SwitchStatus.OFF)) {
log.debug("CELLAR HAZELCAST: {} switch is OFF, cluster event is not consumed", SWITCH_ID);
}
}
}
@Override
public void start() {
isConsuming = true;
if (topic != null) {
registrationId = topic.addMessageListener(this);
} else {
topic = instance.getTopic(Constants.TOPIC);
registrationId = topic.addMessageListener(this);
}
}
@Override
public void stop() {
isConsuming = false;
if (topic != null) {
topic.removeMessageListener(registrationId);
}
}
@Override
public Boolean isConsuming() {
return isConsuming;
}
@Override
public void onMessage(Message<E> message) {
consume(message.getMessageObject());
}
public Dispatcher getDispatcher() {
return dispatcher;
}
public void setDispatcher(Dispatcher dispatcher) {
this.dispatcher = dispatcher;
}
public HazelcastInstance getInstance() {
return instance;
}
public void setInstance(HazelcastInstance instance) {
this.instance = instance;
}
public ITopic getTopic() {
return topic;
}
public void setTopic(ITopic topic) {
this.topic = topic;
}
@Override
public Switch getSwitch() {
// load the switch status from the config
try {
Configuration configuration = configurationAdmin.getConfiguration(Configurations.NODE, null);
if (configuration != null) {
Boolean status = new Boolean((String) configuration.getProperties().get(Configurations.CONSUMER));
if (status) {
eventSwitch.turnOn();
} else {
eventSwitch.turnOff();
}
}
} catch (Exception e) {
// ignore
}
return eventSwitch;
}
public Node getNode() {
return node;
}
public void setNode(Node node) {
this.node = node;
}
public ConfigurationAdmin getConfigurationAdmin() {
return configurationAdmin;
}
public void setConfigurationAdmin(ConfigurationAdmin configurationAdmin) {
this.configurationAdmin = configurationAdmin;
}
}

View File

@ -0,0 +1,18 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ru.entaxy.esb.platform.runtime</groupId>
<artifactId>core</artifactId>
<version>1.8.1</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>cluster</artifactId>
<packaging>pom</packaging>
<name>ENTAXY :: PLATFORM :: CORE :: CLUSTER</name>
<description>ENTAXY :: PLATFORM :: CORE :: CLUSTER</description>
<modules>
<module>cluster-persistence-service</module>
</modules>
</project>

View File

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

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ru.entaxy.esb.platform.runtime</groupId>
<artifactId>core</artifactId>
<version>1.8.1</version>
</parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>infrastructure</artifactId>
<packaging>pom</packaging>
<name>ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INFRASTRUCTURE</name>
<description>ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INFRASTRUCTURE</description>
<modules>
<module>schema</module>
</modules>
</project>

View File

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

View File

@ -0,0 +1,33 @@
# Для использования wsdl, xsd и xsl, которые загружены в шину, необходимо:
**wsdl**
- для использования cxf необходимо подключить "xmlns:cxf="http://cxf.apache.org/blueprint/core"" данный
namespace и подключить к bus, используемый в cxf:
имя cxf необходимо сохранить, в связи с дублированием bus в context
<cxf:bus id="cxf" name="cxf" bus="cxf">
<cxf:features>
<cxf:logging/>
</cxf:features>
</cxf:bus>
также нужно подключить кастомный резолвер для корректного разрешения зависимостей(xsd, wsdl, загруженных ранее в шину)
предварительно мделать импорт пакетов в бандл: ru.entaxy.esb.integration.common.soap
<reference id="cxfDBResourceResolver" interface="org.apache.cxf.resource.ResourceResolver"/>
<bean id="resolver" class="DBResolverSettings" init-method="init">
<property name="bus" ref="cxf"/>
<property name="cxfDBResourceResolver" ref="cxfDBResourceResolver"/>
</bean>
**xslt**
- для использования xslt преобразования необходимо:
<reference id="xslUrlResolver" interface="javax.xml.transform.URIResolver"/>
и дополнительно прописать, при вызове самого компонента:
<to uri="xslt:lama.xsl?uriResolver=#xslUrlResolver"/>
**xsd**
- для использования xsd валидации был разработан отдельный компонент с дополнительными возможностями: динамическим
определением namespace и поиск необходимой xsd в базе данных: (более подробно можно почитать в system/registry/schema/schema-component/README.md)
<to uri="validatorWithDBStorage:namespace:http://www.entaxy.ru/registry-scheme-service/"/>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core</groupId>
<artifactId>infrastructure</artifactId>
<version>1.8.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<groupId>ru.entaxy.esb.platform.runtime.core.infrastructure</groupId>
<artifactId>schema</artifactId>
<name>ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INFRASTRUCTURE :: SCHEMA</name>
<description>ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INFRASTRUCTURE :: SCHEMA</description>
<modules>
<module>schema-component</module>
<module>schema-api</module>
<module>schema-impl</module>
<module>schema-soap</module>
</modules>
</project>

View File

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

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core.infrastructure</groupId>
<artifactId>schema</artifactId>
<version>1.8.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>ru.entaxy.esb.platform.runtime.core.infrastructure.schema</groupId>
<artifactId>schema-api</artifactId>
<packaging>bundle</packaging>
<name>ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INFRASTRUCTURE :: SCHEMA :: API</name>
<description>ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INFRASTRUCTURE :: SCHEMA :: API</description>
<properties>
<bundle.osgi.import.pkg>
javax.persistence;version="[2,3)",
org.hibernate.proxy,
javassist.util.proxy,
*
</bundle.osgi.import.pkg>
<bundle.osgi.export.pkg>
ru.entaxy.esb.platform.runtime.core.infrastructure.schema.api.*
</bundle.osgi.export.pkg>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>${jpa.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-envers</artifactId>
<version>${hibernate.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,64 @@
/*-
* ~~~~~~licensing~~~~~~
* schema-api
* ==========
* 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.esb.platform.runtime.core.infrastructure.schema.api;
import ru.entaxy.esb.platform.runtime.core.infrastructure.schema.api.entity.Resource;
import ru.entaxy.esb.platform.runtime.core.infrastructure.schema.api.entity.ResourceInfo;
import java.util.List;
import java.util.Optional;
public interface ResourceService {
long loadResource(Resource resource);
long reloadResource(Resource resource);
Optional<Resource> getResource(long id);
Optional<Resource> getResourceByNamespace(String namespace);
Optional<Resource> getResourceByName(String name);
Optional<Resource> getResourceByIdAndVersion(long id, String version);
void removeResource(long id);
long loadResourceInfo(ResourceInfo resourceInfo);
long editResourceInfo(ResourceInfo resourceInfo);
Optional<ResourceInfo> getResourceInfo(long id);
Optional<ResourceInfo> getResourceInfoByNamespace(String namespace);
Optional<ResourceInfo> getResourceInfoByName(String name);
Optional<ResourceInfo> getResourceInfoByIdAndVersion(long id, String version);
void removeResourceInfo(long id);
List<ResourceInfo> getListResourceInfo();
List<ResourceInfo> getListResourceInfoByName(String name);
List<ResourceInfo> getListResourceInfoByNamespace(String namespace);
}

View File

@ -0,0 +1,104 @@
/*-
* ~~~~~~licensing~~~~~~
* schema-api
* ==========
* 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.esb.platform.runtime.core.infrastructure.schema.api.entity;
import javax.persistence.*;
import java.util.Arrays;
import java.util.Date;
@Entity
@Table(name = "resource")
public class Resource {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "resource_value")
private byte[] resourceValue;
@Column(name = "created_date")
private Date createdDate;
@Column(name = "created_by")
private String createdBy;
@Column(name = "edited_date")
private Date editedDate;
@Column(name = "edited_by")
private String editedBy;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public byte[] getResourceValue() {
return resourceValue;
}
public void setResourceValue(byte[] resourceValue) {
this.resourceValue = resourceValue;
}
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public Date getEditedDate() {
return editedDate;
}
public void setEditedDate(Date editedDate) {
this.editedDate = editedDate;
}
public String getEditedBy() {
return editedBy;
}
public void setEditedBy(String editedBy) {
this.editedBy = editedBy;
}
@Override
public String toString() {
return "Resource{" +
"id=" + id +
", resourceValue=" + Arrays.toString(resourceValue) +
", createdDate=" + createdDate +
", createdBy='" + createdBy + '\'' +
", editedDate=" + editedDate +
", editedBy='" + editedBy + '\'' +
'}';
}
}

View File

@ -0,0 +1,170 @@
/*-
* ~~~~~~licensing~~~~~~
* schema-api
* ==========
* 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.esb.platform.runtime.core.infrastructure.schema.api.entity;
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name = "resource_info")
public class ResourceInfo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "name")
private String name;
@Column(name = "namespace")
private String namespace;
@Column(name = "description")
private String description;
@Column(name = "version")
private String version;
@Column(name = "convertor")
private Boolean convertor;
@Column(name = "created_date")
private Date createdDate;
@Column(name = "created_by")
private String createdBy;
@Column(name = "edited_date")
private Date editedDate;
@Column(name = "edited_by")
private String editedBy;
@Column(name = "namespace_out")
private String namespaceOut;
@Column(name = "resource_id")
private Long resourceId;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNamespace() {
return namespace;
}
public void setNamespace(String namespace) {
this.namespace = namespace;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public Boolean getConvertor() {
return convertor;
}
public void setConvertor(Boolean convertor) {
this.convertor = convertor;
}
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public Date getEditedDate() {
return editedDate;
}
public void setEditedDate(Date editedDate) {
this.editedDate = editedDate;
}
public String getEditedBy() {
return editedBy;
}
public void setEditedBy(String editedBy) {
this.editedBy = editedBy;
}
public String getNamespaceOut() {
return namespaceOut;
}
public void setNamespaceOut(String namespaceOut) {
this.namespaceOut = namespaceOut;
}
public Long getResourceId() {
return resourceId;
}
public void setResourceId(Long resourceId) {
this.resourceId = resourceId;
}
@Override
public String toString() {
return "ResourceInfo{" +
"id=" + id +
", name='" + name + '\'' +
", namespace='" + namespace + '\'' +
", description='" + description + '\'' +
", version='" + version + '\'' +
", convertor='" + convertor + '\'' +
", createdDate=" + createdDate +
", createdBy='" + createdBy + '\'' +
", editedDate=" + editedDate +
", editedBy='" + editedBy + '\'' +
", namespaceOut='" + namespaceOut + '\'' +
", resourceId=" + resourceId +
'}';
}
}

View File

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

View File

@ -0,0 +1,14 @@
# SCHEMA Component
Компонент для валидации xml с помощью xsd, ранее загруженных в бд через soap(/schema-management)
Сделан на основе camel validator, с заменой загрузчика xsd и ResourceResolver'a(для подгрузки зависимых xsd)
https://camel.apache.org/components/latest/validator-component.html
Компонент работает в двух режимах:
- статический, когда небходимую схему указывают в самом маршруте через namespace, uud или name(версию можно указывать через параметры)
validatorWithDBStorage:namespace:http://www.entaxy.ru/registry-scheme-service/
validatorWithDBStorage:uuid:a7ff793b-d996-42a5-a62b-fb44a2143e98?version=3.0
validatorWithDBStorage:name:lama.xsd?version=3.0
- динамический, если не было указано ничего из выше перечисленного, то будет выбран этот режим.
когда сообщение парсится при поступлении и с помощью namespace загружается его xsd, если xsd была
не найдена или namespace не был указан будет ошибка

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>ru.entaxy.esb.platform.runtime.core.infrastructure</groupId>
<artifactId>schema</artifactId>
<version>1.8.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>ru.entaxy.esb.platform.runtime.core.infrastructure.schema</groupId>
<artifactId>schema-component</artifactId>
<packaging>bundle</packaging>
<name>ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INFRASTRUCTURE :: SCHEMA :: COMPONENT</name>
<description>ENTAXY :: PLATFORM :: RUNTIME :: CORE :: INFRASTRUCTURE :: SCHEMA :: COMPONENT</description>
<properties>
<bundle.osgi.export.service>org.apache.camel.spi.ComponentResolver;component=schema</bundle.osgi.export.service>
<bundle.osgi.import.pkg>
ru.entaxy.esb.system.common.osgi,
ru.entaxy.esb.system.common.osgi.impl,
javax.persistence;version="[2,3)",
*
</bundle.osgi.import.pkg>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<version>${osgi.version}</version>
</dependency>
<dependency>
<groupId>ru.entaxy.esb.platform.runtime.core.infrastructure.schema</groupId>
<artifactId>schema-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>ru.entaxy.esb.system.commons</groupId>
<artifactId>system-commons</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,450 @@
/*-
* ~~~~~~licensing~~~~~~
* schema-component
* ==========
* 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.esb.platform.runtime.core.infrastructure.schema.component;
import org.apache.camel.*;
import org.apache.camel.converter.jaxp.XmlConverter;
import org.apache.camel.support.AsyncProcessorHelper;
import org.apache.camel.support.processor.validation.DefaultValidationErrorHandler;
import org.apache.camel.support.processor.validation.SchemaValidationException;
import org.apache.camel.support.processor.validation.ValidatorErrorHandler;
import org.apache.camel.util.IOHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.ls.LSResourceResolver;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import ru.entaxy.esb.platform.runtime.core.infrastructure.schema.component.exception.SchemaNotFoundException;
import ru.entaxy.esb.platform.runtime.core.infrastructure.schema.component.util.SchemaReaderFromDB;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
/**
* A processor which validates the XML version of the inbound message body
* against some schema either in XSD or RelaxNG
*/
public class ValidatingProcessor implements AsyncProcessor {
private static final Logger LOG = LoggerFactory.getLogger(ValidatingProcessor.class);
private final SchemaReaderFromDB schemaReaderFromDB;
private ValidatorErrorHandler errorHandler = new DefaultValidationErrorHandler();
private final XmlConverter converter = new XmlConverter();
private boolean useDom;
private boolean useSharedSchema = true;
private boolean failOnNullBody = true;
private boolean failOnNullHeader = true;
private String headerName;
private String uri;
private final Map<String, Schema> schemaMap = new HashMap<>();
public ValidatingProcessor() {
schemaReaderFromDB = new SchemaReaderFromDB();
}
public ValidatingProcessor(SchemaReaderFromDB schemaReaderFromDB, String uri) {
// schema reader can be a singelton per schema, therefore make reuse, see ValidatorEndpoint and ValidatorProducer
this.schemaReaderFromDB = schemaReaderFromDB;
this.uri = uri;
}
public void process(Exchange exchange) throws Exception {
AsyncProcessorHelper.process(this, exchange);
}
public boolean process(Exchange exchange, AsyncCallback callback) {
try {
doProcess(exchange);
} catch (Exception e) {
exchange.setException(e);
}
callback.done(true);
return true;
}
@Override
public CompletableFuture<Exchange> processAsync(Exchange exchange) {
return null;
}
protected void doProcess(Exchange exchange) throws Exception {
Schema schema = null;
Validator validator = null;
if (uri != null && !uri.isEmpty()) {
schema = getOrCreateSchema(schemaReaderFromDB.getSchemaResourceUri());
validator = getValidator(schema);
}
// the underlying input stream, which we need to close to avoid locking files or other resources
Source source = null;
InputStream is = null;
try {
Result result = null;
// only convert to input stream if really needed
if (isInputStreamNeeded(exchange)) {
is = getContentToValidate(exchange, InputStream.class);
if (is != null) {
source = getSource(exchange, is);
}
} else {
Object content = getContentToValidate(exchange);
if (content != null) {
source = getSource(exchange, content);
}
}
//CAMEL-7036 We don't need to set the result if the source is an instance of StreamSource
if (source instanceof DOMSource) {
result = new DOMResult();
} else if (source instanceof SAXSource) {
result = new SAXResult();
} else if (source instanceof StAXSource || source instanceof StreamSource) {
result = null;
}
if (source != null) {
if (validator == null) {
String namespace = "namespace:" + getNamespace(source);
schemaReaderFromDB.setSchemaResourceUri(namespace);
schema = getOrCreateSchema(namespace);
validator = getValidator(schema);
}
if (validator == null)
throw new SchemaNotFoundException("Schema not found for {" + schemaReaderFromDB.getSchemaResourceUri() + "}");
// create a new errorHandler and set it on the validator
// must be a local instance to avoid problems with concurrency (to be
// thread safe)
ValidatorErrorHandler handler = errorHandler.getClass().newInstance();
validator.setErrorHandler(handler);
try {
LOG.trace("Validating {}", source);
validator.validate(source, result);
handler.handleErrors(exchange, schema, result);
} catch (SAXParseException e) {
// can be thrown for non well formed XML
throw new SchemaValidationException(exchange, schema, Collections.singletonList(e),
Collections.emptyList(),
Collections.emptyList());
}
}
} finally {
IOHelper.close(is);
}
}
private String getNamespace(Source source) throws ParserConfigurationException, IOException, SAXException {
StreamSource domSource = (StreamSource) source;
domSource.getInputStream();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(domSource.getInputStream());
return document.getDocumentElement().getNamespaceURI();
}
private Schema getOrCreateSchema(String resourceUri) throws IOException, SAXException {
if (!schemaMap.containsKey(resourceUri) && resourceUri != null && !resourceUri.isEmpty()) {
schemaMap.put(resourceUri, createSchema());
}
return resourceUri == null ? null : schemaMap.get(resourceUri);
}
private Validator getValidator(Schema schema) {
return schema != null ? schema.newValidator() : null;
}
private Object getContentToValidate(Exchange exchange) {
if (shouldUseHeader()) {
return exchange.getIn().getHeader(headerName);
} else {
return exchange.getIn().getBody();
}
}
private <T> T getContentToValidate(Exchange exchange, Class<T> clazz) {
if (shouldUseHeader()) {
return exchange.getIn().getHeader(headerName, clazz);
} else {
return exchange.getIn().getBody(clazz);
}
}
private boolean shouldUseHeader() {
return headerName != null;
}
public void loadSchema() throws Exception {
schemaReaderFromDB.loadSchema();
}
// Properties
// -----------------------------------------------------------------------
public Schema getSchema() throws IOException, SAXException {
return schemaReaderFromDB.getSchema();
}
public void setSchema(Schema schema) {
schemaReaderFromDB.setSchema(schema);
}
public String getSchemaLanguage() {
return schemaReaderFromDB.getSchemaLanguage();
}
public void setSchemaLanguage(String schemaLanguage) {
schemaReaderFromDB.setSchemaLanguage(schemaLanguage);
}
public Source getSchemaSource() throws IOException {
return schemaReaderFromDB.getSchemaSource();
}
public void setSchemaSource(Source schemaSource) {
schemaReaderFromDB.setSchemaSource(schemaSource);
}
public URL getSchemaUrl() {
return schemaReaderFromDB.getSchemaUrl();
}
public void setSchemaUrl(URL schemaUrl) {
schemaReaderFromDB.setSchemaUrl(schemaUrl);
}
public File getSchemaFile() {
return schemaReaderFromDB.getSchemaFile();
}
public void setSchemaFile(File schemaFile) {
schemaReaderFromDB.setSchemaFile(schemaFile);
}
public byte[] getSchemaAsByteArray() {
return schemaReaderFromDB.getSchemaAsByteArray();
}
public void setSchemaAsByteArray(byte[] schemaAsByteArray) {
schemaReaderFromDB.setSchemaAsByteArray(schemaAsByteArray);
}
public SchemaFactory getSchemaFactory() {
return schemaReaderFromDB.getSchemaFactory();
}
public void setSchemaFactory(SchemaFactory schemaFactory) {
schemaReaderFromDB.setSchemaFactory(schemaFactory);
}
public ValidatorErrorHandler getErrorHandler() {
return errorHandler;
}
public void setErrorHandler(ValidatorErrorHandler errorHandler) {
this.errorHandler = errorHandler;
}
@Deprecated
public boolean isUseDom() {
return useDom;
}
/**
* Sets whether DOMSource and DOMResult should be used.
*
* @param useDom true to use DOM otherwise
*/
@Deprecated
public void setUseDom(boolean useDom) {
this.useDom = useDom;
}
public boolean isUseSharedSchema() {
return useSharedSchema;
}
public void setUseSharedSchema(boolean useSharedSchema) {
this.useSharedSchema = useSharedSchema;
}
public LSResourceResolver getResourceResolver() {
return schemaReaderFromDB.getResourceResolver();
}
public void setResourceResolver(LSResourceResolver resourceResolver) {
schemaReaderFromDB.setResourceResolver(resourceResolver);
}
public boolean isFailOnNullBody() {
return failOnNullBody;
}
public void setFailOnNullBody(boolean failOnNullBody) {
this.failOnNullBody = failOnNullBody;
}
public boolean isFailOnNullHeader() {
return failOnNullHeader;
}
public void setFailOnNullHeader(boolean failOnNullHeader) {
this.failOnNullHeader = failOnNullHeader;
}
public String getHeaderName() {
return headerName;
}
public void setHeaderName(String headerName) {
this.headerName = headerName;
}
// Implementation methods
// -----------------------------------------------------------------------
protected SchemaFactory createSchemaFactory() {
return schemaReaderFromDB.createSchemaFactory();
}
protected Source createSchemaSource() throws IOException {
return schemaReaderFromDB.createSchemaSource();
}
protected Schema createSchema() throws SAXException, IOException {
return schemaReaderFromDB.createSchema();
}
/**
* Checks whether we need an {@link InputStream} to access the message body or header.
* <p/>
* Depending on the content in the message body or header, we may not need to convert
* to {@link InputStream}.
*
* @param exchange the current exchange
* @return <tt>true</tt> to convert to {@link InputStream} beforehand converting to {@link Source} afterwards.
*/
protected boolean isInputStreamNeeded(Exchange exchange) {
Object content = getContentToValidate(exchange);
if (content == null) {
return false;
}
if (content instanceof InputStream) {
return true;
} else if (content instanceof Source) {
return false;
} else if (content instanceof String) {
return false;
} else if (content instanceof byte[]) {
return false;
} else //there is a direct and hopefully optimized converter to Source
if (content instanceof Node) {
return false;
} else return exchange.getContext().getTypeConverterRegistry().lookup(Source.class, content.getClass()) == null;
// yes an input stream is needed
}
/**
* Converts the inbound body or header to a {@link Source}, if it is <b>not</b> already a {@link Source}.
* <p/>
* This implementation will prefer to source in the following order:
* <ul>
* <li>DOM - DOM if explicit configured to use DOM</li>
* <li>SAX - SAX as 2nd choice</li>
* <li>Stream - Stream as 3rd choice</li>
* <li>DOM - DOM as 4th choice</li>
* </ul>
*/
protected Source getSource(Exchange exchange, Object content) {
if (isUseDom()) {
// force DOM
return exchange.getContext().getTypeConverter().tryConvertTo(DOMSource.class, exchange, content);
}
// body or header may already be a source
if (content instanceof Source) {
return (Source) content;
}
Source source = null;
if (content instanceof InputStream) {
return new StreamSource((InputStream) content);
}
if (content != null) {
TypeConverter tc = exchange.getContext().getTypeConverterRegistry().lookup(Source.class, content.getClass());
if (tc != null) {
source = tc.convertTo(Source.class, exchange, content);
}
}
if (source == null) {
// then try SAX
source = exchange.getContext().getTypeConverter().tryConvertTo(SAXSource.class, exchange, content);
}
if (source == null) {
// then try stream
source = exchange.getContext().getTypeConverter().tryConvertTo(StreamSource.class, exchange, content);
}
if (source == null) {
// and fallback to DOM
source = exchange.getContext().getTypeConverter().tryConvertTo(DOMSource.class, exchange, content);
}
if (source == null) {
if (isFailOnNullBody()) {
throw new ExpectedBodyTypeException(exchange, Source.class);
} else {
try {
source = converter.toDOMSource(converter.createDocument());
} catch (ParserConfigurationException e) {
throw new RuntimeTransformException(e);
}
}
}
return source;
}
}

View File

@ -0,0 +1,38 @@
/*-
* ~~~~~~licensing~~~~~~
* schema-component
* ==========
* 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.esb.platform.runtime.core.infrastructure.schema.component;
import org.apache.camel.Endpoint;
import org.apache.camel.support.DefaultComponent;
import java.util.Map;
public class ValidatorWithDBStorageComponent extends DefaultComponent {
@Override
protected Endpoint createEndpoint(String uri, String xsdScheme, Map<String, Object> parameters) throws Exception {
ValidatorWithDBStorageEndpoint endpoint = new ValidatorWithDBStorageEndpoint(uri, this);
endpoint.setUri(uri);
setProperties(endpoint, parameters);
return endpoint;
}
}

View File

@ -0,0 +1,131 @@
/*-
* ~~~~~~licensing~~~~~~
* schema-component
* ==========
* 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.esb.platform.runtime.core.infrastructure.schema.component;
import org.apache.camel.Component;
import org.apache.camel.Consumer;
import org.apache.camel.Processor;
import org.apache.camel.Producer;
import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.UriEndpoint;
import org.apache.camel.spi.UriParam;
import org.apache.camel.spi.UriPath;
import org.apache.camel.support.DefaultEndpoint;
import org.osgi.framework.FrameworkUtil;
import org.w3c.dom.ls.LSResourceResolver;
import ru.entaxy.esb.platform.runtime.core.infrastructure.schema.component.util.SchemaReaderFromDB;
import ru.entaxy.esb.system.common.osgi.OSGIUtils;
import ru.entaxy.esb.platform.runtime.core.infrastructure.schema.api.ResourceService;
@UriEndpoint(
scheme = "validatorWithDBStorage",
title = "ValidatorWithDBStorage",
syntax = "validatorWithDBStorage:namespace",
label = "Custom validator component with loader resources from db",
producerOnly = true)
public class ValidatorWithDBStorageEndpoint extends DefaultEndpoint {
@UriPath(description = "URL to a local resource on the classpath, or a reference to lookup a bean in the Registry,"
+ " or a full URL to a remote resource or resource on the file system which contains the XSD to validate against.")
@Metadata(required = true)
private String uri;
@UriParam(description = "Version")
@Metadata(required = true)
private String version;
/**
* We need a one-to-one relation between endpoint and schema reader in order
* to be able to clear the cached schema in the schema reader. See method
*/
private final SchemaReaderFromDB schemaReaderFromDB;
private volatile boolean schemaReaderConfigured;
private ResourceService resourceService;
private LSResourceResolver resourceResolver;
public ValidatorWithDBStorageEndpoint(String uri, Component component) {
super(uri, component);
this.uri = uri.replace("validatorWithDBStorage://", "").replace("validatorWithDBStorage:", "").replace("validatorWithDBStorage", "");
schemaReaderFromDB = this.uri.isEmpty() ? new SchemaReaderFromDB() :
new SchemaReaderFromDB(getCamelContext(), this.uri, version);
}
public Producer createProducer() throws Exception {
if (!schemaReaderConfigured) {
if (resourceResolver != null) {
schemaReaderFromDB.setResourceResolver(getResourceResolver());
}
schemaReaderFromDB.setResourceService(getResourceService());
// force loading of schema at create time otherwise concurrent
// processing could cause thread safe issues for the
// javax.xml.validation.SchemaFactory
schemaReaderFromDB.loadSchema();
// configure only once
schemaReaderConfigured = true;
}
ValidatingProcessor validator = new ValidatingProcessor(schemaReaderFromDB, uri);
return new ValidatorWithDBStorageProducer(this, validator);
}
public Consumer createConsumer(Processor processor) throws Exception {
return null;
}
public boolean isSingleton() {
return true;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public ResourceService getResourceService() {
if (resourceService == null) {
resourceService = (ResourceService) OSGIUtils.getServiceReference(
FrameworkUtil.getBundle(ValidatorWithDBStorageEndpoint.class).getBundleContext(),
ResourceService.class.getName());
}
return resourceService;
}
private LSResourceResolver getResourceResolver() {
if (resourceResolver == null) {
resourceResolver = (LSResourceResolver) OSGIUtils.getServiceReference(
FrameworkUtil.getBundle(ValidatorWithDBStorageEndpoint.class).getBundleContext(),
LSResourceResolver.class.getName());
}
return resourceResolver;
}
public void setVersion(String version) {
this.version = version;
}
public String getVersion() {
return version;
}
}

View File

@ -0,0 +1,63 @@
/*-
* ~~~~~~licensing~~~~~~
* schema-component
* ==========
* 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.esb.platform.runtime.core.infrastructure.schema.component;
import org.apache.camel.AsyncCallback;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
import org.apache.camel.support.DefaultAsyncProducer;
import org.apache.camel.support.service.ServiceHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ValidatorWithDBStorageProducer extends DefaultAsyncProducer {
private static final Logger LOG = LoggerFactory.getLogger(ValidatorWithDBStorageProducer.class);
private final ValidatingProcessor validatingProcessor;
public ValidatorWithDBStorageProducer(Endpoint endpoint, ValidatingProcessor validatingProcessor) {
super(endpoint);
this.validatingProcessor = validatingProcessor;
}
@Override
public boolean process(Exchange exchange, AsyncCallback callback) {
return validatingProcessor.process(exchange, callback);
}
@Override
protected void doStart() throws Exception {
super.doStart();
ServiceHelper.startService(validatingProcessor);
}
@Override
protected void doStop() throws Exception {
super.doStop();
ServiceHelper.stopService(validatingProcessor);
}
@Override
protected void doShutdown() throws Exception {
super.doStop();
ServiceHelper.stopAndShutdownService(validatingProcessor);
}
}

View File

@ -0,0 +1,47 @@
/*-
* ~~~~~~licensing~~~~~~
* schema-component
* ==========
* 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.esb.platform.runtime.core.infrastructure.schema.component.exception;
public class SchemaNotFoundException extends Exception {
private static final long serialVersionUID = 948229285513408917L;
public SchemaNotFoundException() {
super();
}
public SchemaNotFoundException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public SchemaNotFoundException(String message, Throwable cause) {
super(message, cause);
}
public SchemaNotFoundException(String message) {
super(message);
}
public SchemaNotFoundException(Throwable cause) {
super(cause);
}
}

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