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>