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

@ -6,7 +6,7 @@
<parent>
<groupId>ru.entaxy.esb.system.auth.basic</groupId>
<artifactId>basic-auth</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
</parent>
<groupId>ru.entaxy.esb.system.auth.basic.api</groupId>

View File

@ -31,6 +31,8 @@ public interface BasicAuthService {
List<BasicAuthAccount> list();
Optional<BasicAuthAccount> get(String login);
Optional<BasicAuthAccount> getBySystem(String systemUuid);
Optional<BasicAuthAccount> getByAuthorizationHeaderHash(String authorizationHeaderHash);

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ru.entaxy.esb.system.auth.basic</groupId>
<artifactId>basic-auth</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
</parent>
<groupId>ru.entaxy.esb.system.auth.basic.impl</groupId>
@ -35,6 +35,12 @@
org.apache.commons.codec.binary,
*
</bundle.osgi.import.pkg>
<!-- bundle.osgi.private.pkg>
ru.entaxy.esb.system.auth.basic.interceptor,
ru.entaxy.esb.system.auth.basic.jpa.impl,
ru.entaxy.esb.system.auth.basic.jpa.listener,
ru.entaxy.esb.system.auth.basic.jpa.util
</bundle.osgi.private.pkg -->
</properties>
<dependencies>
@ -75,7 +81,6 @@
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
<version>${osgi.version}</version>
<scope>provided</scope>
</dependency>
<dependency>

View File

@ -105,6 +105,23 @@ public class BasicAuthServiceImpl implements BasicAuthService {
return basicAuthAccount;
}
public Optional<BasicAuthAccount> getBySystem(String systemUuid){
Optional<BasicAuthAccount> basicAuthAccount;
try (Session s = getSession()) {
s.getTransaction().begin();
CriteriaBuilder builder = s.getCriteriaBuilder();
CriteriaQuery<BasicAuthAccount> criteriaQuery = builder.createQuery(BasicAuthAccount.class);
Root<BasicAuthAccount> root = criteriaQuery.from(BasicAuthAccount.class);
criteriaQuery.where(builder.equal(root.get("systemUUID"), systemUuid));
basicAuthAccount = s.createQuery(criteriaQuery).uniqueResultOptional();
s.getTransaction().commit();
s.close();
}
return basicAuthAccount;
};
public Optional<BasicAuthAccount> get(Session session, String login) {
Optional<BasicAuthAccount> basicAuthAccount;
CriteriaBuilder builder = session.getCriteriaBuilder();

View File

@ -29,7 +29,7 @@ import org.hibernate.event.spi.EventType;
public class EntityEventListenerRegistry {
private static final Log LOG = LogFactory.getLog(EntityEventListenerRegistry.class);
private static final int SESSION_WAIT_TIMEOUT = 5000;
private static final int SESSION_WAIT_TIMEOUT = 50000;
private SessionFactory sessionFactory;
private BasicAuthPostEventListener basicAuthPostEventListener;

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>basic-auth</artifactId>
<groupId>ru.entaxy.esb.system.auth.basic</groupId>
<version>1.8.0</version>
<version>1.8.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@ -107,7 +107,7 @@
<log message="\r\n${headers.NTX_AccountPassword}\r\n" loggingLevel="DEBUG"/>
<log message="\r\n${headers.NTX_AccountSystemUUID}\r\n" loggingLevel="DEBUG"/>
<to uri="bean-fix:basicAuthService?method=saveCommon(${headers.NTX_AccountLogin}, ${headers.NTX_AccountPassword},
<to uri="bean:basicAuthService?method=saveCommon(${headers.NTX_AccountLogin}, ${headers.NTX_AccountPassword},
${headers.NTX_AccountSystemUUID}, ${headers.X-ForwardedUser}, ${headers.X-ForwardedUser})"/>
</split>
<setBody>
@ -138,7 +138,7 @@
<xpath resultType="String">//bas:login</xpath>
</setHeader>
<log message="\r\n${headers.NTX_Login}\r\n" loggingLevel="DEBUG"/>
<to uri="bean-fix:basicAuthService?method=remove(${headers.NTX_Login})"/>
<to uri="bean:basicAuthService?method=remove(${headers.NTX_Login})"/>
</split>
<setBody>
<constant>&lt;response xmlns="http://www.entaxy.ru/basic-auth-service/"&gt;true&lt;/response&gt;
@ -168,7 +168,7 @@
<log message="\r\n${exchangeProperty.NTX_SubjectType}\r\n" loggingLevel="DEBUG"/>
<log message="\r\n${exchangeProperty.NTX_Action}\r\n" loggingLevel="DEBUG"/>
<to uri="bean-fix:basicAuthService?method=get(${exchangeProperty.NTX_Login})"/>
<to uri="bean:basicAuthService?method=get(${exchangeProperty.NTX_Login})"/>
<choice>
<when>
@ -181,17 +181,17 @@
<choice>
<when>
<simple>${headers.operationName} == 'addAccountPermission'</simple>
<to uri="bean-fix:permissionService?method=addIfNotExist(${exchangeProperty.NTX_Action.id}, 'account', ${exchangeProperty.NTX_Subject},
<to uri="bean:permissionService?method=addIfNotExist(${exchangeProperty.NTX_Action.id}, 'account', ${exchangeProperty.NTX_Subject},
${exchangeProperty.NTX_SubjectType}, ${exchangeProperty.NTX_Action})"/>
</when>
<when>
<simple>${headers.operationName} == 'removeAccountPermission'</simple>
<to uri="bean-fix:permissionService?method=remove(${exchangeProperty.NTX_Action.id}, 'account', ${exchangeProperty.NTX_Subject},
<to uri="bean:permissionService?method=remove(${exchangeProperty.NTX_Action.id}, 'account', ${exchangeProperty.NTX_Subject},
${exchangeProperty.NTX_SubjectType}, ${exchangeProperty.NTX_Action})"/>
</when>
</choice>
<to uri="bean-fix:basicAuthService?method=saveFull(${exchangeProperty.NTX_Action.login}, ${exchangeProperty.NTX_Action.passwordHash},
<to uri="bean:basicAuthService?method=saveFull(${exchangeProperty.NTX_Action.login}, ${exchangeProperty.NTX_Action.passwordHash},
${exchangeProperty.NTX_Action.encryptionAlgorithm.getAlgorithmName()},
${exchangeProperty.NTX_Action.getSystemUUID()}, ${exchangeProperty.NTX_Action.authorizationHeaderHash},
${exchangeProperty.NTX_Action.description}, ${exchangeProperty.NTX_Action.createdBy},

View File

@ -62,16 +62,17 @@ htpasswd.file.directory=/mnt/share
* KARAF_HOST_NAMES=("http://192.168.122.93:9091" "http://192.168.122.94:9091") - караф сервера с запущеным сервисом htpasswd
* HTPASSWD_STORAGE=/etc/nginx/htpasswd - адрес файла htpasswd, на который настроен nginX
* LOGFILE="htpasswd-sync.log" - адрес лог файла
Добавить запуск скрипта через cron
sudo crontab -e
```
раз в минут
*/5 * * * * <path_to_script>
*/5 * * * * <path_to_script> >> <path_to_log_file> 2>&1
либо раз в минуту
*/1 * * * * <path_to_script>
*/1 * * * * <path_to_script> >> <path_to_log_file> 2>&1
```

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ru.entaxy.esb.system.auth.basic</groupId>
<artifactId>basic-auth</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
</parent>
<groupId>ru.entaxy.esb.system.auth.basic.htpasswd</groupId>
@ -20,6 +20,10 @@
<bundle.osgi.export.pkg>
ru.entaxy.esb.system.auth.basic.htpasswd,
</bundle.osgi.export.pkg>
<!-- bundle.osgi.private.pkg>
ru.entaxy.esb.system.auth.basic.htpasswd.entity,
ru.entaxy.esb.system.auth.basic.htpasswd.rest
</bundle.osgi.private.pkg -->
<bundle.osgi.import.pkg>
ru.entaxy.esb.system.auth.basic.jpa.api,
ru.entaxy.esb.system.auth.basic.jpa.api.entity,
@ -46,7 +50,6 @@
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel.karaf</groupId>

View File

@ -17,7 +17,7 @@
# limitations under the License.
# ~~~~~~/licensing~~~~~~
###
# !/bin/sh
#!/bin/bash
KARAF_HOST_NAMES=("http://192.168.122.93:9091" "http://192.168.122.94:9091")
HTPASSWD_PATH=/htpasswd
CHECKSUM_PATH=$HTPASSWD_PATH/checksum

View File

@ -7,7 +7,7 @@
<parent>
<groupId>ru.entaxy.esb.system.auth</groupId>
<artifactId>system-auth</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
</parent>
<groupId>ru.entaxy.esb.system.auth.basic</groupId>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>ru.entaxy.esb.system</groupId>
<artifactId>system-parent</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
</parent>
<groupId>ru.entaxy.esb.system.auth</groupId>

View File

@ -8,7 +8,7 @@
<parent>
<groupId>ru.entaxy.esb.system</groupId>
<artifactId>system-parent</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
</parent>
<groupId>ru.entaxy.esb.system.commons</groupId>
@ -61,12 +61,17 @@
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>${xerces.version}</version>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.osgi</groupId>
@ -89,7 +94,6 @@
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
<version>${osgi.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
@ -158,5 +162,10 @@
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-base</artifactId>
<version>${camel.version}-ENTAXY</version>
</dependency>
</dependencies>
</project>

View File

@ -1,221 +0,0 @@
/*-
* ~~~~~~licensing~~~~~~
* system-commons
* ==========
* Copyright (C) 2020 - 2021 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.esb.system.common.aggregation;
import com.hazelcast.core.HazelcastInstance;
import org.apache.camel.*;
import org.apache.camel.model.OptionalIdentifiedDefinition;
import org.apache.camel.model.ToDefinition;
import org.apache.camel.model.language.SimpleExpression;
import org.apache.camel.processor.CamelInternalProcessor;
import org.apache.camel.processor.aggregate.AggregationStrategyBeanAdapter;
import org.apache.camel.reifier.ProcessorReifier;
import org.apache.camel.spi.AggregationRepository;
import org.apache.camel.spi.IdAware;
import org.apache.camel.spi.RouteIdAware;
import org.apache.camel.util.concurrent.SynchronousExecutorService;
import ru.entaxy.esb.system.common.aggregation.hazelcast.DisconnectedMembershipListener;
import ru.entaxy.esb.system.common.aggregation.repo.IgniteAggregationRepository;
public class AggregationProcessorBean implements Processor {
private static final String routeName = "aggregation";
private CamelContext camelContext;
private String aggregationStrategyRef;
private AggregationStrategy aggregationStrategy;
private String aggregationStrategyMethodName;
private String aggregateExpression = "ENTAXY_AcknowledgeMsgID";
private String toDefinition = "direct-vm:common-revert-no-acknowledge-messages?block=true&timeout=60000";
private int completionSize = 2;
//10 min in mc
private int completionTimeout = 600_000;
private String aggregationRepositoryRef;
private AggregationRepository aggregationRepository;
private HazelcastInstance hazelcastInstance;
private AggregationProcessorWithRestoreTimeout aggregationProcessorWithRestoreTimeout;
public void initAggregateProcessor() throws Exception {
Route route = camelContext.getRoute(routeName);
aggregationProcessorWithRestoreTimeout = new AggregationProcessorWithRestoreTimeout(camelContext,
getCamelDestinationProcessor(route),
getCorrelationExpression(route),
createAggregationStrategy(camelContext),
new SynchronousExecutorService(),
false);
settingsAggregationProcessorWithRestoreTimeout(route);
aggregationProcessorWithRestoreTimeout.doStart();
addHazelcastMembershipListener();
}
private void settingsAggregationProcessorWithRestoreTimeout(Route route) {
AggregationRepository repository = createAggregationRepository(route);
if (repository != null) {
aggregationProcessorWithRestoreTimeout.setAggregationRepository(repository);
}
aggregationProcessorWithRestoreTimeout.setCompletionSize(completionSize);
aggregationProcessorWithRestoreTimeout.setCompletionTimeout(completionTimeout);
}
private void addHazelcastMembershipListener() {
hazelcastInstance.getCluster().addMembershipListener(new DisconnectedMembershipListener(aggregationProcessorWithRestoreTimeout, camelContext));
}
private Expression getCorrelationExpression(Route route) {
return new SimpleExpression(aggregateExpression);
}
private CamelInternalProcessor getCamelDestinationProcessor(Route route) throws Exception {
Processor childProcessor = createChildProcessor(route, true);
// wrap the aggregate route in a unit of work processor
CamelInternalProcessor internal = new CamelInternalProcessor(camelContext, childProcessor);
internal.addAdvice(new CamelInternalProcessor.UnitOfWorkProcessorAdvice(route, camelContext));
return internal;
}
private Processor createChildProcessor(Route route, boolean mandatory) throws Exception {
Processor children = null;
ToDefinition definition = new ToDefinition(toDefinition);
// at first use custom factory
if (camelContext.adapt(ExtendedCamelContext.class).getProcessorFactory() != null) {
children = camelContext.adapt(ExtendedCamelContext.class).getProcessorFactory().createChildProcessor(route,
definition, mandatory);
}
// fallback to default implementation if factory did not create the
// child
if (children == null) {
children = createOutputsProcessor(route, definition);
}
if (children == null && mandatory) {
throw new IllegalArgumentException("Definition has no children on " + definition);
}
return children;
}
protected Processor createOutputsProcessor(Route route, ToDefinition definition) throws Exception {
Processor processor = ProcessorReifier.reifier(route, definition).createProcessor();
// inject id
if (processor instanceof IdAware) {
String id = getId(definition);
((IdAware) processor).setId(id);
}
if (processor instanceof RouteIdAware) {
((RouteIdAware) processor).setRouteId(route.getRouteId());
}
return processor;
}
protected String getId(OptionalIdentifiedDefinition<?> def) {
return def.idOrCreate(camelContext.adapt(ExtendedCamelContext.class).getNodeIdFactory());
}
private AggregationRepository createAggregationRepository(Route route) {
if (aggregationRepository == null && aggregationRepositoryRef != null) {
aggregationRepository = (AggregationRepository) route.getCamelContext().getRegistry().lookupByName(aggregationRepositoryRef);
}
return aggregationRepository;
}
private AggregationStrategy createAggregationStrategy(CamelContext camelContext) {
if (aggregationStrategy == null && aggregationStrategyRef != null) {
Object aggStrategy = camelContext.getRegistry().lookupByNameAndType(aggregationStrategyRef, Object.class);
if (aggStrategy instanceof AggregationStrategy) {
aggregationStrategy = (AggregationStrategy) aggStrategy;
} else if (aggStrategy != null) {
aggregationStrategy = new AggregationStrategyBeanAdapter(aggStrategy, aggregationStrategyMethodName);
} else {
throw new IllegalArgumentException("Cannot find AggregationStrategy in Registry with name: " + aggregationStrategyRef);
}
}
if (aggregationStrategy == null) {
throw new IllegalArgumentException("AggregationStrategy or AggregationStrategyRef must be set on " + this);
}
if (aggregationStrategy instanceof CamelContextAware) {
((CamelContextAware) aggregationStrategy).setCamelContext(camelContext);
}
return aggregationStrategy;
}
@Override
public void process(Exchange exchange) throws Exception {
aggregationProcessorWithRestoreTimeout.process(exchange);
}
public void setCamelContext(CamelContext camelContext) {
this.camelContext = camelContext;
}
public void setAggregationStrategyRef(String aggregationStrategyRef) {
this.aggregationStrategyRef = aggregationStrategyRef;
}
public void setAggregationStrategy(AggregationStrategy aggregationStrategy) {
this.aggregationStrategy = aggregationStrategy;
}
public void setAggregationStrategyMethodName(String aggregationStrategyMethodName) {
this.aggregationStrategyMethodName = aggregationStrategyMethodName;
}
public void setAggregateExpression(String aggregateExpression) {
this.aggregateExpression = aggregateExpression;
}
public void setToDefinition(String toDefinition) {
this.toDefinition = toDefinition;
}
public void setCompletionSize(int completionSize) {
this.completionSize = completionSize;
}
public void setCompletionTimeout(int completionTimeout) {
this.completionTimeout = completionTimeout;
}
public void setAggregationRepositoryRef(String aggregationRepositoryRef) {
this.aggregationRepositoryRef = aggregationRepositoryRef;
}
public void setHazelcastInstance(HazelcastInstance hazelcastInstance) {
this.hazelcastInstance = hazelcastInstance;
}
public void init() throws Exception {
camelContext.addStartupListener((a, b) -> initAggregateProcessor());
}
public void doStop() throws Exception {
aggregationProcessorWithRestoreTimeout.doStop();
if (aggregationRepository instanceof IgniteAggregationRepository)
((IgniteAggregationRepository) aggregationRepository).doStop();
}
}

View File

@ -19,25 +19,21 @@
*/
package ru.entaxy.esb.system.common.aggregation.hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.MemberAttributeEvent;
import com.hazelcast.core.MembershipEvent;
import com.hazelcast.core.MembershipListener;
import org.apache.camel.CamelContext;
import org.apache.camel.processor.aggregate.AggregateProcessorSetter;
import org.apache.camel.processor.aggregate.EntaxyAggregateProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.entaxy.esb.system.common.aggregation.AggregationProcessorWithRestoreTimeout;
public class DisconnectedMembershipListener implements MembershipListener {
public class DisconnectedMembershipListener implements MembershipListener, AggregateProcessorSetter {
protected static final Logger log = LoggerFactory.getLogger(DisconnectedMembershipListener.class);
private final AggregationProcessorWithRestoreTimeout aggregationProcessorWithRestoreTimeout;
private final CamelContext camelContext;
public DisconnectedMembershipListener(AggregationProcessorWithRestoreTimeout aggregationProcessorWithRestoreTimeout,
CamelContext camelContext) {
this.aggregationProcessorWithRestoreTimeout = aggregationProcessorWithRestoreTimeout;
this.camelContext = camelContext;
}
private CamelContext camelContext;
private EntaxyAggregateProcessor aggregateProcessor;
@Override
public void memberAdded(MembershipEvent membershipEvent) {
@ -46,8 +42,8 @@ public class DisconnectedMembershipListener implements MembershipListener {
@Override
public void memberRemoved(MembershipEvent membershipEvent) {
try {
aggregationProcessorWithRestoreTimeout.recoverCompletedMessageFromAggregationRepository(camelContext);
aggregationProcessorWithRestoreTimeout.restoreTimeoutMapFromAggregationRepository();
aggregateProcessor.recoverCompletedMessageFromAggregationRepository(camelContext);
aggregateProcessor.restoreTimeoutMapFromAggregationRepository();
} catch (Exception e) {
log.error("Can't restore Timeout from Aggregator. Please restart bundle.", e);
}
@ -56,4 +52,17 @@ public class DisconnectedMembershipListener implements MembershipListener {
@Override
public void memberAttributeChanged(MemberAttributeEvent memberAttributeEvent) {
}
@Override
public void setAggregateProcessor(EntaxyAggregateProcessor aggregateProcessor) {
this.aggregateProcessor = aggregateProcessor;
}
public void setHazelcastInstance(HazelcastInstance hazelcastInstance) {
hazelcastInstance.getCluster().addMembershipListener(this);
}
public void setCamelContext(CamelContext camelContext) {
this.camelContext = camelContext;
}
}

View File

@ -1,201 +0,0 @@
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

@ -1,45 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ru.entaxy.esb.system</groupId>
<artifactId>system-parent</artifactId>
<version>1.8.0</version>
</parent>
<artifactId>component-bean-fix</artifactId>
<version>1.8.0</version>
<packaging>bundle</packaging>
<name>CAMEL COMPONENT :: BEAN :: FIX</name>
<description>CAMEL COMPONENT :: BEAN :: FIX</description>
<dependencies>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-support</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-bean</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
<executions>
<execution>
<id>update-file-header</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,249 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.*;
import org.apache.camel.support.AsyncProcessorSupport;
import org.apache.camel.support.service.ServiceHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A {@link Processor} which converts the inbound exchange to a method
* invocation on a POJO
*/
public abstract class AbstractBeanProcessor extends AsyncProcessorSupport {
private static final Logger LOG = LoggerFactory.getLogger(AbstractBeanProcessor.class);
private final BeanHolder beanHolder;
private transient Processor processor;
private transient boolean lookupProcessorDone;
private final Object lock = new Object();
private BeanScope scope;
private String method;
private boolean shorthandMethod;
public AbstractBeanProcessor(Object pojo, BeanInfo beanInfo) {
this(new ConstantBeanHolder(pojo, beanInfo));
}
public AbstractBeanProcessor(Object pojo, CamelContext camelContext, ParameterMappingStrategy parameterMappingStrategy) {
this(pojo, new BeanInfo(camelContext, pojo.getClass(), parameterMappingStrategy));
}
public AbstractBeanProcessor(Object pojo, CamelContext camelContext) {
this(pojo, camelContext, BeanInfo.createParameterMappingStrategy(camelContext));
}
public AbstractBeanProcessor(BeanHolder beanHolder) {
this.beanHolder = beanHolder;
}
@Override
public String toString() {
return "BeanProcessor[" + beanHolder + (method != null ? "#" + method : "") + "]";
}
@Override
public boolean process(Exchange exchange, AsyncCallback callback) {
// do we have an explicit method name we always should invoke (either configured on endpoint or as a header)
String explicitMethodName = exchange.getIn().getHeader(Exchange.BEAN_METHOD_NAME, method, String.class);
Object bean;
BeanInfo beanInfo;
try {
bean = beanHolder.getBean(exchange);
// get bean info for this bean instance (to avoid thread issue)
beanInfo = beanHolder.getBeanInfo(bean);
if (beanInfo == null) {
// fallback and use old way
beanInfo = beanHolder.getBeanInfo();
}
} catch (Throwable e) {
exchange.setException(e);
callback.done(true);
return true;
}
// do we have a custom adapter for this POJO to a Processor
// but only do this if allowed
// we need to check beanHolder is Processor is support, to avoid the bean cached issue
if (allowProcessor(explicitMethodName, beanInfo)) {
Processor target = getProcessor();
if (target == null) {
// only attempt to lookup the processor once or nearly once
// allow cache by default or if the scope is singleton
boolean allowCache = scope == null || scope == BeanScope.Singleton;
if (allowCache) {
if (!lookupProcessorDone) {
synchronized (lock) {
lookupProcessorDone = true;
// so if there is a custom type converter for the bean to processor
target = exchange.getContext().getTypeConverter().tryConvertTo(Processor.class, exchange, bean);
processor = target;
}
}
} else {
// so if there is a custom type converter for the bean to processor
target = exchange.getContext().getTypeConverter().tryConvertTo(Processor.class, exchange, bean);
}
}
if (target != null) {
if (LOG.isTraceEnabled()) {
LOG.trace("Using a custom adapter as bean invocation: {}", target);
}
try {
target.process(exchange);
} catch (Throwable e) {
exchange.setException(e);
}
callback.done(true);
return true;
}
}
Message in = exchange.getIn();
// set explicit method name to invoke as a header, which is how BeanInfo can detect it
if (explicitMethodName != null) {
in.setHeader(Exchange.BEAN_METHOD_NAME, explicitMethodName);
}
MethodInvocation invocation;
try {
invocation = beanInfo.createInvocation(bean, exchange);
} catch (Throwable e) {
exchange.setException(e);
callback.done(true);
return true;
} finally {
// must remove headers as they were provisional
if (explicitMethodName != null) {
in.removeHeader(Exchange.BEAN_METHOD_NAME);
}
}
if (invocation == null) {
exchange.setException(new IllegalStateException("No method invocation could be created, no matching method could be found on: " + bean));
callback.done(true);
return true;
}
// invoke invocation
return invocation.proceed(callback);
}
protected Processor getProcessor() {
return processor;
}
protected BeanHolder getBeanHolder() {
return this.beanHolder;
}
public Object getBean() {
return beanHolder.getBean(null);
}
// Properties
// -----------------------------------------------------------------------
public String getMethod() {
return method;
}
public BeanScope getScope() {
return scope;
}
public void setScope(BeanScope scope) {
this.scope = scope;
}
/**
* Sets the method name to use
*/
public void setMethod(String method) {
this.method = method;
}
public boolean isShorthandMethod() {
return shorthandMethod;
}
/**
* Sets whether to support getter style method name, so you can
* say the method is called 'name' but it will invoke the 'getName' method.
* <p/>
* Is by default turned off.
*/
public void setShorthandMethod(boolean shorthandMethod) {
this.shorthandMethod = shorthandMethod;
}
// Implementation methods
//-------------------------------------------------------------------------
@Override
protected void doStart() throws Exception {
// optimize to only get (create) a processor if really needed
if (beanHolder.supportProcessor() && allowProcessor(method, beanHolder.getBeanInfo())) {
processor = beanHolder.getProcessor();
ServiceHelper.startService(processor);
} else if (beanHolder instanceof ConstantBeanHolder) {
try {
// Start the bean if it implements Service interface and if cached
// so meant to be reused
ServiceHelper.startService(beanHolder.getBean(null));
} catch (NoSuchBeanException e) {
// ignore
}
}
}
@Override
protected void doStop() throws Exception {
if (processor != null) {
ServiceHelper.stopService(processor);
} else if (beanHolder instanceof ConstantBeanHolder) {
try {
// Stop the bean if it implements Service interface and if cached
// so meant to be reused
ServiceHelper.stopService(beanHolder.getBean(null));
} catch (NoSuchBeanException e) {
// ignore
}
}
}
private boolean allowProcessor(String explicitMethodName, BeanInfo info) {
if (explicitMethodName != null) {
// don't allow if explicit method name is given, as we then must invoke this method
return false;
}
// don't allow if any of the methods has a @Handler annotation
// as the @Handler annotation takes precedence and is supposed to trigger invocation
// of the given method
if (info.hasAnyMethodHandlerAnnotation()) {
return false;
}
// fallback and allow using the processor
return true;
}
}

View File

@ -1,321 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.*;
import org.apache.camel.support.DefaultExchange;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.StringHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
public abstract class AbstractCamelInvocationHandler implements InvocationHandler {
private static final Logger LOG = LoggerFactory.getLogger(CamelInvocationHandler.class);
private static final List<Method> EXCLUDED_METHODS = new ArrayList<>();
private static ExecutorService executorService;
protected final Endpoint endpoint;
protected final Producer producer;
static {
// exclude all java.lang.Object methods as we dont want to invoke them
EXCLUDED_METHODS.addAll(Arrays.asList(Object.class.getMethods()));
}
public AbstractCamelInvocationHandler(Endpoint endpoint, Producer producer) {
this.endpoint = endpoint;
this.producer = producer;
}
private static Object getBody(Exchange exchange, Class<?> type) throws InvalidPayloadException {
if (exchange.getMessage().getBody() != null) {
return exchange.getMessage().getMandatoryBody(type);
} else {
return null;
}
}
@Override
public final Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
if (isValidMethod(method)) {
return doInvokeProxy(proxy, method, args);
} else {
// invalid method then invoke methods on this instead
if ("toString".equals(method.getName())) {
return this.toString();
} else if ("hashCode".equals(method.getName())) {
return this.hashCode();
} else if ("equals".equals(method.getName())) {
return Boolean.FALSE;
}
return null;
}
}
public abstract Object doInvokeProxy(Object proxy, Method method, Object[] args) throws Throwable;
@SuppressWarnings("unchecked")
protected Object invokeProxy(final Method method, final ExchangePattern pattern, Object[] args, boolean binding) throws Throwable {
final Exchange exchange = new DefaultExchange(endpoint, pattern);
//Need to check if there are mutiple arguments and the parameters have no annotations for binding,
//then use the original bean invocation.
boolean canUseBinding = method.getParameterCount() == 1;
if (!canUseBinding) {
for (Parameter parameter : method.getParameters()) {
if (parameter.isAnnotationPresent(Header.class)
|| parameter.isAnnotationPresent(Headers.class)
|| parameter.isAnnotationPresent(ExchangeProperty.class)
|| parameter.isAnnotationPresent(Body.class)) {
canUseBinding = true;
}
}
}
if (binding && canUseBinding) {
// in binding mode we bind the passed in arguments (args) to the created exchange
// using the existing Camel @Body, @Header, @Headers, @ExchangeProperty annotations
// if no annotation then its bound as the message body
int index = 0;
for (Annotation[] row : method.getParameterAnnotations()) {
Object value = args[index];
if (row == null || row.length == 0) {
// assume its message body when there is no annotations
exchange.getIn().setBody(value);
} else {
for (Annotation ann : row) {
if (ann.annotationType().isAssignableFrom(Header.class)) {
Header header = (Header) ann;
String name = header.value();
exchange.getIn().setHeader(name, value);
} else if (ann.annotationType().isAssignableFrom(Headers.class)) {
Map map = exchange.getContext().getTypeConverter().tryConvertTo(Map.class, exchange, value);
if (map != null) {
exchange.getIn().getHeaders().putAll(map);
}
} else if (ann.annotationType().isAssignableFrom(ExchangeProperty.class)) {
ExchangeProperty ep = (ExchangeProperty) ann;
String name = ep.value();
exchange.setProperty(name, value);
} else if (ann.annotationType().isAssignableFrom(Body.class)) {
exchange.getIn().setBody(value);
} else {
// assume its message body when there is no annotations
exchange.getIn().setBody(value);
}
}
}
index++;
}
} else {
if (args != null) {
if (args.length == 1) {
exchange.getIn().setBody(args[0]);
} else {
exchange.getIn().setBody(args);
}
}
}
if (binding) {
LOG.trace("Binding to service interface as @Body,@Header,@ExchangeProperty detected when calling proxy method: {}", method);
} else {
LOG.trace("No binding to service interface as @Body,@Header,@ExchangeProperty not detected when calling proxy method: {}", method);
}
return doInvoke(method, exchange);
}
protected Object invokeWithBody(final Method method, Object body, final ExchangePattern pattern) throws Throwable {
final Exchange exchange = new DefaultExchange(endpoint, pattern);
exchange.getIn().setBody(body);
return doInvoke(method, exchange);
}
protected Object doInvoke(final Method method, final Exchange exchange) throws Throwable {
// is the return type a future
final boolean isFuture = method.getReturnType() == Future.class;
// create task to execute the proxy and gather the reply
FutureTask<Object> task = new FutureTask<>(new Callable<Object>() {
public Object call() throws Exception {
// process the exchange
LOG.trace("Proxied method call {} invoking producer: {}", method.getName(), producer);
producer.process(exchange);
Object answer = afterInvoke(method, exchange, exchange.getPattern(), isFuture);
LOG.trace("Proxied method call {} returning: {}", method.getName(), answer);
return answer;
}
});
if (isFuture) {
// submit task and return future
if (LOG.isTraceEnabled()) {
LOG.trace("Submitting task for exchange id {}", exchange.getExchangeId());
}
getExecutorService(exchange.getContext()).submit(task);
return task;
} else {
// execute task now
try {
task.run();
return task.get();
} catch (ExecutionException e) {
// we don't want the wrapped exception from JDK
throw e.getCause();
}
}
}
protected Object afterInvoke(Method method, Exchange exchange, ExchangePattern pattern, boolean isFuture) throws Exception {
// check if we had an exception
Throwable cause = exchange.getException();
if (cause != null) {
Throwable found = findSuitableException(cause, method);
if (found != null) {
if (found instanceof Exception) {
throw (Exception) found;
} else {
// wrap as exception
throw new CamelExchangeException("Error processing exchange", exchange, cause);
}
}
// special for runtime camel exceptions as they can be nested
if (cause instanceof RuntimeCamelException) {
// if the inner cause is a runtime exception we can throw it
// directly
if (cause.getCause() instanceof RuntimeException) {
throw (RuntimeException) ((RuntimeCamelException) cause).getCause();
}
throw (RuntimeCamelException) cause;
}
// okay just throw the exception as is
if (cause instanceof Exception) {
throw (Exception) cause;
} else {
// wrap as exception
throw new CamelExchangeException("Error processing exchange", exchange, cause);
}
}
Class<?> to = isFuture ? getGenericType(exchange.getContext(), method.getGenericReturnType()) : method.getReturnType();
// do not return a reply if the method is VOID
if (to == Void.TYPE) {
return null;
}
return getBody(exchange, to);
}
protected static Class<?> getGenericType(CamelContext context, Type type) throws ClassNotFoundException {
if (type == null) {
// fallback and use object
return Object.class;
}
// unfortunately java dont provide a nice api for getting the generic
// type of the return type
// due type erasure, so we have to gather it based on a String
// representation
String name = StringHelper.between(type.toString(), "<", ">");
if (name != null) {
if (name.contains("<")) {
// we only need the outer type
name = StringHelper.before(name, "<");
}
return context.getClassResolver().resolveMandatoryClass(name);
} else {
// fallback and use object
return Object.class;
}
}
protected static synchronized ExecutorService getExecutorService(CamelContext context) {
// CamelContext will shutdown thread pool when it shutdown so we can
// lazy create it on demand
// but in case of hot-deploy or the likes we need to be able to
// re-create it (its a shared static instance)
if (executorService == null || executorService.isTerminated() || executorService.isShutdown()) {
// try to lookup a pool first based on id/profile
executorService = context.getRegistry().lookupByNameAndType("CamelInvocationHandler", ExecutorService.class);
if (executorService == null) {
executorService = context.getExecutorServiceManager().newThreadPool(CamelInvocationHandler.class, "CamelInvocationHandler", "CamelInvocationHandler");
}
if (executorService == null) {
executorService = context.getExecutorServiceManager().newDefaultThreadPool(CamelInvocationHandler.class, "CamelInvocationHandler");
}
}
return executorService;
}
/**
* Tries to find the best suited exception to throw.
* <p/>
* It looks in the exception hierarchy from the caused exception and matches
* this against the declared exceptions being thrown on the method.
*
* @param cause the caused exception
* @param method the method
* @return the exception to throw, or <tt>null</tt> if not possible to find
* a suitable exception
*/
protected Throwable findSuitableException(Throwable cause, Method method) {
if (method.getExceptionTypes() == null || method.getExceptionTypes().length == 0) {
return null;
}
// see if there is any exception which matches the declared exception on
// the method
for (Class<?> type : method.getExceptionTypes()) {
Object fault = ObjectHelper.getException(type, cause);
if (fault != null) {
return Throwable.class.cast(fault);
}
}
return null;
}
protected boolean isValidMethod(Method method) {
// must not be in the excluded list
for (Method excluded : EXCLUDED_METHODS) {
if (ObjectHelper.isOverridingMethod(excluded, method)) {
// the method is overriding an excluded method so its not valid
return false;
}
}
return true;
}
}

View File

@ -1,43 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.Exchange;
import org.apache.camel.RuntimeExchangeException;
import java.util.Collection;
/**
* An exception thrown if an attempted method invocation resulted in an ambiguous method
* such that multiple methods match the inbound message exchange
*/
public class AmbiguousMethodCallException extends RuntimeExchangeException {
private final Collection<MethodInfo> methods;
public AmbiguousMethodCallException(Exchange exchange, Collection<MethodInfo> methods) {
super("Ambiguous method invocations possible: " + methods, exchange);
this.methods = methods;
}
/**
* The ambiguous methods for which a single method could not be chosen
*/
public Collection<MethodInfo> getMethods() {
return methods;
}
}

View File

@ -1,67 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.CamelContext;
import org.apache.camel.Expression;
import org.apache.camel.spi.Language;
import org.apache.camel.support.ObjectHelper;
import org.apache.camel.support.language.DefaultAnnotationExpressionFactory;
import org.apache.camel.support.language.LanguageAnnotation;
import org.apache.camel.util.StringHelper;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class BeanAnnotationExpressionFactory extends DefaultAnnotationExpressionFactory {
@Override
public Expression createExpression(CamelContext camelContext, Annotation annotation, LanguageAnnotation languageAnnotation, Class<?> expressionReturnType) {
String beanName = getFromAnnotation(annotation, "ref");
String method = getFromAnnotation(annotation, "method");
// ref is mandatory
StringHelper.notEmpty(beanName, "ref", annotation);
// method is optional but provide it as null to the bean expression
if (org.apache.camel.util.ObjectHelper.isEmpty(method)) {
method = null;
}
Language lan = camelContext.resolveLanguage("bean");
if (method != null) {
return lan.createExpression(beanName + "?method=" + method);
} else {
return lan.createExpression(beanName);
}
}
protected String getFromAnnotation(Annotation annotation, String attribute) {
try {
Method method = annotation.getClass().getMethod(attribute);
Object value = ObjectHelper.invokeMethod(method, annotation);
if (value == null) {
throw new IllegalArgumentException("Cannot determine the " + attribute + " from the annotation: " + annotation);
}
return value.toString();
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException("Cannot determine the " + attribute
+ " of the annotation: " + annotation + " as it does not have a " + attribute + "() method");
}
}
}

View File

@ -1,117 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.BeanScope;
import org.apache.camel.Endpoint;
import org.apache.camel.spi.Metadata;
import org.apache.camel.support.DefaultComponent;
import org.apache.camel.support.LRUCache;
import org.apache.camel.support.LRUCacheFactory;
import org.apache.camel.util.PropertiesHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
/**
* The bean component is for invoking Java beans from Camel.
*/
@org.apache.camel.spi.annotations.Component("bean-fix")
public class BeanComponent extends DefaultComponent {
private static final Logger LOG = LoggerFactory.getLogger(BeanComponent.class);
// use an internal soft cache for BeanInfo as they are costly to introspect
// for example the bean language using OGNL expression runs much faster reusing the BeanInfo from this cache
@SuppressWarnings("unchecked")
private final Map<BeanInfoCacheKey, BeanInfo> beanInfoCache = LRUCacheFactory.newLRUSoftCache(1000);
@Deprecated
@Metadata(defaultValue = "true", description = "Use singleton option instead.")
private Boolean cache;
@Metadata(defaultValue = "Singleton", description = "Scope of bean."
+ " When using singleton scope (default) the bean is created or looked up only once and reused for the lifetime of the endpoint."
+ " The bean should be thread-safe in case concurrent threads is calling the bean at the same time."
+ " When using request scope the bean is created or looked up once per request (exchange). This can be used if you want to store state on a bean"
+ " while processing a request and you want to call the same bean instance multiple times while processing the request."
+ " The bean does not have to be thread-safe as the instance is only called from the same request."
+ " When using delegate scope, then the bean will be looked up or created per call. However in case of lookup then this is delegated "
+ " to the bean registry such as Spring or CDI (if in use), which depends on their configuration can act as either singleton or prototype scope."
+ " so when using prototype then this depends on the delegated registry.")
private BeanScope scope = BeanScope.Singleton;
public BeanComponent() {
}
// Implementation methods
//-----------------------------------------------------------------------
@Override
protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
BeanEndpoint endpoint = new BeanEndpoint(uri, this);
endpoint.setBeanName(remaining);
if (cache != null) {
endpoint.setCache(cache);
}
endpoint.setScope(scope);
setProperties(endpoint, parameters);
// the bean.xxx options is for the bean
Map<String, Object> options = PropertiesHelper.extractProperties(parameters, "bean.");
endpoint.setParameters(options);
return endpoint;
}
BeanInfo getBeanInfoFromCache(BeanInfoCacheKey key) {
return beanInfoCache.get(key);
}
void addBeanInfoToCache(BeanInfoCacheKey key, BeanInfo beanInfo) {
beanInfoCache.put(key, beanInfo);
}
@Override
protected void doShutdown() throws Exception {
if (LOG.isDebugEnabled() && beanInfoCache instanceof LRUCache) {
LRUCache cache = (LRUCache) this.beanInfoCache;
LOG.debug("Clearing BeanInfo cache[size={}, hits={}, misses={}, evicted={}]", cache.size(), cache.getHits(), cache.getMisses(), cache.getEvicted());
}
beanInfoCache.clear();
}
@Deprecated
public Boolean getCache() {
return scope == BeanScope.Singleton;
}
@Deprecated
public void setCache(Boolean cache) {
if (cache) {
scope = BeanScope.Singleton;
} else {
scope = BeanScope.Prototype;
}
}
public BeanScope getScope() {
return scope;
}
public void setScope(BeanScope scope) {
this.scope = scope;
}
}

View File

@ -1,26 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
public final class BeanConstants {
public static final String BEAN_PARAMETER_MAPPING_STRATEGY = "CamelBeanParameterMappingStrategy";
private BeanConstants() {
// Utility class
}
}

View File

@ -1,185 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.*;
import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.UriEndpoint;
import org.apache.camel.spi.UriParam;
import org.apache.camel.spi.UriPath;
import org.apache.camel.support.DefaultEndpoint;
import java.util.Map;
/**
* Invoke methods of Java beans stored in Camel registry.
*/
@UriEndpoint(firstVersion = "1.0.0", scheme = "bean", title = "Bean", syntax = "bean:beanName", producerOnly = true, category = {Category.CORE, Category.JAVA})
public class BeanEndpoint extends DefaultEndpoint {
private transient BeanHolder beanHolder;
private transient BeanProcessor processor;
@UriPath(label = "common", description = "Sets the name of the bean to invoke")
@Metadata(required = true)
private String beanName;
@UriParam(label = "common", description = "Sets the name of the method to invoke on the bean")
private String method;
@Deprecated
@UriParam(label = "common", description = "Use scope option instead.")
private Boolean cache;
@UriParam(label = "common", defaultValue = "Singleton", description = "Scope of bean."
+ " When using singleton scope (default) the bean is created or looked up only once and reused for the lifetime of the endpoint."
+ " The bean should be thread-safe in case concurrent threads is calling the bean at the same time."
+ " When using request scope the bean is created or looked up once per request (exchange). This can be used if you want to store state on a bean"
+ " while processing a request and you want to call the same bean instance multiple times while processing the request."
+ " The bean does not have to be thread-safe as the instance is only called from the same request."
+ " When using prototype scope, then the bean will be looked up or created per call. However in case of lookup then this is delegated "
+ " to the bean registry such as Spring or CDI (if in use), which depends on their configuration can act as either singleton or prototype scope."
+ " so when using prototype then this depends on the delegated registry.")
private BeanScope scope = BeanScope.Singleton;
@UriParam(prefix = "bean.", label = "advanced", description = "Used for configuring additional properties on the bean", multiValue = true)
private Map<String, Object> parameters;
public BeanEndpoint() {
setExchangePattern(ExchangePattern.InOut);
}
public BeanEndpoint(String endpointUri, Component component, BeanProcessor processor) {
super(endpointUri, component);
this.processor = processor;
setExchangePattern(ExchangePattern.InOut);
}
public BeanEndpoint(String endpointUri, Component component) {
super(endpointUri, component);
setExchangePattern(ExchangePattern.InOut);
}
@Override
public Producer createProducer() throws Exception {
return new BeanProducer(this, processor);
}
@Override
public Consumer createConsumer(Processor processor) throws Exception {
throw new UnsupportedOperationException("You cannot consume from a bean endpoint");
}
public BeanProcessor getProcessor() {
return processor;
}
@Override
protected void doInit() throws Exception {
super.doInit();
if (processor == null) {
BeanHolder holder = getBeanHolder();
if (holder == null) {
RegistryBean registryBean = new RegistryBean(getCamelContext(), beanName);
if (scope == BeanScope.Singleton) {
// if singleton then create a cached holder that use the same singleton instance
holder = registryBean.createCacheHolder();
} else {
holder = registryBean;
}
}
if (scope == BeanScope.Request) {
// wrap in registry scoped
holder = new RequestBeanHolder(holder);
}
processor = new BeanProcessor(holder);
if (method != null) {
processor.setMethod(method);
}
processor.setScope(scope);
if (parameters != null) {
holder.setOptions(parameters);
}
}
}
@Override
protected void doStop() throws Exception {
super.doStop();
// noop
}
// Properties
//-------------------------------------------------------------------------
public String getBeanName() {
return beanName;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
@Deprecated
public Boolean getCache() {
return scope == BeanScope.Singleton;
}
@Deprecated
public void setCache(Boolean cache) {
if (cache) {
scope = BeanScope.Singleton;
} else {
scope = BeanScope.Prototype;
}
}
public BeanScope getScope() {
return scope;
}
public void setScope(BeanScope scope) {
this.scope = scope;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public BeanHolder getBeanHolder() {
return beanHolder;
}
public void setBeanHolder(BeanHolder beanHolder) {
this.beanHolder = beanHolder;
}
public Map<String, Object> getParameters() {
return parameters;
}
public void setParameters(Map<String, Object> parameters) {
this.parameters = parameters;
}
// Implementation methods
//-------------------------------------------------------------------------
@Override
protected String createEndpointUri() {
return "bean:" + getBeanName() + (method != null ? "?method=" + method : "");
}
}

View File

@ -1,28 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
/**
* A bean processor that is optimised for being invoked one time from an {@link org.apache.camel.language.bean.BeanExpression}.
* Where as {@link BeanProcessor} is a bean that is a {@link org.apache.camel.Service} and intended for long lifecycle.
*/
public class BeanExpressionProcessor extends AbstractBeanProcessor {
public BeanExpressionProcessor(BeanHolder beanHolder) {
super(beanHolder);
}
}

View File

@ -1,136 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.spi.ClassResolver;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.StringHelper;
/**
* Helper for the bean component.
*/
public final class BeanHelper {
private BeanHelper() {
// utility class
}
/**
* Determines and maps the given value is valid according to the supported
* values by the bean component.
*
* @param value the value
* @return the parameter type the given value is being mapped as, or <tt>null</tt> if not valid.
*/
public static Class<?> getValidParameterType(String value) {
if (ObjectHelper.isEmpty(value)) {
return null;
}
// trim value
value = value.trim();
// single quoted is valid
if (value.startsWith("'") && value.endsWith("'")) {
return String.class;
}
// double quoted is valid
if (value.startsWith("\"") && value.endsWith("\"")) {
return String.class;
}
// true or false is valid (boolean)
if (value.equals("true") || value.equals("false")) {
return Boolean.class;
}
// null is valid (to force a null value)
if (value.equals("null")) {
return Object.class;
}
// simple language tokens is valid
if (StringHelper.hasStartToken(value, "simple")) {
return Object.class;
}
// numeric is valid
boolean numeric = true;
for (char ch : value.toCharArray()) {
if (!Character.isDigit(ch)) {
numeric = false;
break;
}
}
if (numeric) {
return Number.class;
}
// not valid
return null;
}
/**
* Determines if the given value is valid according to the supported
* values by the bean component.
*
* @param value the value
* @return <tt>true</tt> if valid, <tt>false</tt> otherwise
*/
public static boolean isValidParameterValue(String value) {
if (ObjectHelper.isEmpty(value)) {
// empty value is valid
return true;
}
return getValidParameterType(value) != null;
}
/**
* Determines if the given parameter type is assignable to the expected type.
* <p/>
* This implementation will check if the given parameter type matches the expected type as class using either
* <ul>
* <li>FQN class name - com.foo.MyOrder</li>
* <li>Simple class name - MyOrder</li>
* </ul>
* If the given parameter type is <b>not</b> a class, then <tt>null</tt> is returned
*
* @param resolver the class resolver
* @param parameterType the parameter type as a String, can be a FQN or a simple name of the class
* @param expectedType the expected type
* @return <tt>null</tt> if parameter type is <b>not</b> a class, <tt>true</tt> if parameter type is assignable, <tt>false</tt> if not assignable
*/
public static Boolean isAssignableToExpectedType(ClassResolver resolver, String parameterType, Class<?> expectedType) {
// if its a class, then it should be assignable
Class<?> parameterClass = resolver.resolveClass(parameterType);
if (parameterClass == null && parameterType.equals(expectedType.getSimpleName())) {
// it was not the FQN class name, but the simple name instead, which matched
return true;
}
// not a class so return null
if (parameterClass == null) {
return null;
}
// if there was a class, then it must be assignable to match
return parameterClass.isAssignableFrom(expectedType);
}
}

View File

@ -1,76 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.Exchange;
import org.apache.camel.NoSuchBeanException;
import org.apache.camel.Processor;
import java.util.Map;
/**
* Object holder for a bean.
*/
public interface BeanHolder {
/**
* Additional options that should be configured on the bean
*/
Map<String, Object> getOptions();
/**
* Sets additional options that should be configured on the bean
*/
void setOptions(Map<String, Object> options);
/**
* Gets the bean.
*
* @throws NoSuchBeanException is thrown if the bean cannot be found.
*/
Object getBean(Exchange exchange) throws NoSuchBeanException;
/**
* Gets a {@link Processor} for this bean, if supported.
*
* @return the {@link Processor}, or <tt>null</tt> if not supported.
*/
Processor getProcessor();
/**
* Whether a {@link Processor} is supported by this bean holder.
*
* @return <tt>true</tt> if the holder can supporting using a processor, <tt>false</tt> otherwise
*/
boolean supportProcessor();
/**
* Gets bean info for the bean.
*/
BeanInfo getBeanInfo();
/**
* Gets bean info for the given bean.
* <p/>
* This implementation allows a thread safe usage for {@link BeanHolder} implementations
* such as the {@link RegistryBean}.
*
* @param bean the bean
* @return <tt>null</tt> if not supported, then use {@link #getBeanInfo()} instead.
*/
BeanInfo getBeanInfo(Object bean);
}

View File

@ -1,61 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import java.lang.reflect.Method;
/**
* A key used for caching {@link BeanInfo} by the {@link BeanComponent}
*/
public final class BeanInfoCacheKey {
private final Class<?> type;
private final Method explicitMethod;
public BeanInfoCacheKey(Class<?> type, Method explicitMethod) {
this.type = type;
this.explicitMethod = explicitMethod;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
BeanInfoCacheKey that = (BeanInfoCacheKey) o;
if (explicitMethod != null ? !explicitMethod.equals(that.explicitMethod) : that.explicitMethod != null) {
return false;
}
if (!type.equals(that.type)) {
return false;
}
return true;
}
@Override
public int hashCode() {
int result = type.hashCode();
result = 31 * result + (explicitMethod != null ? explicitMethod.hashCode() : 0);
return result;
}
}

View File

@ -1,129 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.*;
import org.apache.camel.support.service.ServiceSupport;
import java.util.concurrent.CompletableFuture;
public class BeanProcessor extends ServiceSupport implements AsyncProcessor {
private final DelegateBeanProcessor delegate;
public BeanProcessor(Object pojo, BeanInfo beanInfo) {
this.delegate = new DelegateBeanProcessor(pojo, beanInfo);
}
public BeanProcessor(Object pojo, CamelContext camelContext, ParameterMappingStrategy parameterMappingStrategy) {
this.delegate = new DelegateBeanProcessor(pojo, camelContext, parameterMappingStrategy);
}
public BeanProcessor(Object pojo, CamelContext camelContext) {
this.delegate = new DelegateBeanProcessor(pojo, camelContext);
}
public BeanProcessor(BeanHolder beanHolder) {
this.delegate = new DelegateBeanProcessor(beanHolder);
}
@Override
public void process(Exchange exchange) throws Exception {
delegate.process(exchange);
}
@Override
public boolean process(Exchange exchange, AsyncCallback callback) {
return delegate.process(exchange, callback);
}
@Override
public CompletableFuture<Exchange> processAsync(Exchange exchange) {
return delegate.processAsync(exchange);
}
public Processor getProcessor() {
return delegate.getProcessor();
}
public BeanHolder getBeanHolder() {
return delegate.getBeanHolder();
}
public Object getBean() {
return delegate.getBean();
}
public String getMethod() {
return delegate.getMethod();
}
public void setMethod(String method) {
delegate.setMethod(method);
}
public BeanScope getScope() {
return delegate.getScope();
}
public void setScope(BeanScope scope) {
delegate.setScope(scope);
}
public boolean isShorthandMethod() {
return delegate.isShorthandMethod();
}
public void setShorthandMethod(boolean shorthandMethod) {
delegate.setShorthandMethod(shorthandMethod);
}
@Override
protected void doStart() throws Exception {
delegate.doStart();
}
@Override
protected void doStop() throws Exception {
delegate.doStop();
}
@Override
public String toString() {
return delegate.toString();
}
private static final class DelegateBeanProcessor extends AbstractBeanProcessor {
public DelegateBeanProcessor(Object pojo, BeanInfo beanInfo) {
super(pojo, beanInfo);
}
public DelegateBeanProcessor(Object pojo, CamelContext camelContext, ParameterMappingStrategy parameterMappingStrategy) {
super(pojo, camelContext, parameterMappingStrategy);
}
public DelegateBeanProcessor(Object pojo, CamelContext camelContext) {
super(pojo, camelContext);
}
public DelegateBeanProcessor(BeanHolder beanHolder) {
super(beanHolder);
}
}
}

View File

@ -1,73 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.AsyncCallback;
import org.apache.camel.Exchange;
import org.apache.camel.NoSuchBeanException;
import org.apache.camel.support.DefaultAsyncProducer;
import org.apache.camel.support.service.ServiceHelper;
/**
* Bean {@link org.apache.camel.Producer}
*/
public class BeanProducer extends DefaultAsyncProducer {
private final BeanProcessor processor;
private boolean beanStarted;
public BeanProducer(BeanEndpoint endpoint, BeanProcessor processor) {
super(endpoint);
this.processor = processor;
this.beanStarted = false;
}
@Override
public boolean process(Exchange exchange, AsyncCallback callback) {
return processor.process(exchange, callback);
}
@Override
protected void doStart() throws Exception {
super.doStart();
if (processor.getBeanHolder() instanceof ConstantBeanHolder) {
try {
// Start the bean if it implements Service interface and if cached
// so meant to be reused
ServiceHelper.startService(processor.getBean());
beanStarted = true;
} catch (NoSuchBeanException e) {
}
}
}
@Override
protected void doStop() throws Exception {
if (beanStarted) {
try {
// Stop the bean if it implements Service interface and if cached
// so meant to be reused
ServiceHelper.stopService(processor.getBean());
beanStarted = false;
} catch (NoSuchBeanException e) {
}
}
super.doStop();
}
}

View File

@ -1,26 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
/**
* Object holder for a bean type.
*/
public interface BeanTypeHolder extends BeanHolder {
Class<?> getType();
}

View File

@ -1,47 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.Endpoint;
import org.apache.camel.ExchangePattern;
import org.apache.camel.Producer;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* An {@link java.lang.reflect.InvocationHandler} which invokes a message
* exchange on a camel {@link Endpoint}
*/
public class CamelInvocationHandler extends AbstractCamelInvocationHandler implements InvocationHandler {
private final MethodInfoCache methodInfoCache;
private final boolean binding;
public CamelInvocationHandler(Endpoint endpoint, boolean binding, Producer producer, MethodInfoCache methodInfoCache) {
super(endpoint, producer);
this.binding = binding;
this.methodInfoCache = methodInfoCache;
}
@Override
public Object doInvokeProxy(Object proxy, Method method, Object[] args) throws Throwable {
MethodInfo methodInfo = methodInfoCache.getMethodInfo(method);
final ExchangePattern pattern = methodInfo != null ? methodInfo.getPattern() : ExchangePattern.InOut;
return invokeProxy(method, pattern, args, binding);
}
}

View File

@ -1,105 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.support.CamelContextHelper;
import org.apache.camel.support.PropertyBindingSupport;
import org.apache.camel.util.ObjectHelper;
import java.util.Map;
/**
* A constant (singleton) bean implementation of {@link org.apache.camel.component.bean.BeanHolder}
*/
public class ConstantBeanHolder implements BeanHolder {
private final Object bean;
private final BeanInfo beanInfo;
private Processor processor;
private Map<String, Object> options;
public ConstantBeanHolder(Object bean, BeanInfo beanInfo) {
ObjectHelper.notNull(bean, "bean");
ObjectHelper.notNull(beanInfo, "beanInfo");
this.bean = bean;
this.beanInfo = beanInfo;
}
public ConstantBeanHolder(Object bean, CamelContext context) {
ObjectHelper.notNull(bean, "bean");
this.bean = bean;
this.beanInfo = new BeanInfo(context, bean.getClass());
}
@Override
public Map<String, Object> getOptions() {
return options;
}
@Override
public void setOptions(Map<String, Object> options) {
this.options = options;
// since its a constant we can set the options immediately on the bean
if (options != null && !options.isEmpty()) {
PropertyBindingSupport.build()
.withRemoveParameters(false)
.withCamelContext(getBeanInfo().getCamelContext())
.withProperties(options)
.withTarget(bean)
.bind();
}
}
@Override
public String toString() {
// avoid invoke toString on bean as it may be a remote proxy
return ObjectHelper.className(bean) + "(" + ObjectHelper.getIdentityHashCode(bean) + ")";
}
@Override
public Object getBean(Exchange exchange) {
return bean;
}
@Override
public Processor getProcessor() {
if (this.processor == null) {
this.processor = CamelContextHelper.convertTo(beanInfo.getCamelContext(), Processor.class, bean);
}
return this.processor;
}
@Override
public boolean supportProcessor() {
return true;
}
@Override
public BeanInfo getBeanInfo() {
return beanInfo;
}
@Override
public BeanInfo getBeanInfo(Object bean) {
return null;
}
}

View File

@ -1,37 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
/**
* A constant {@link org.apache.camel.component.bean.BeanHolder} for a class or static class
* where the intention is to only invoke static methods, without the need for creating an instance of the type.
*/
public class ConstantStaticTypeBeanHolder extends ConstantTypeBeanHolder {
public ConstantStaticTypeBeanHolder(Class<?> type, CamelContext context) {
super(type, context);
}
@Override
public Object getBean(Exchange exchange) {
// we cannot create a bean as there is no default constructor
return null;
}
}

View File

@ -1,116 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.support.PropertyBindingSupport;
import org.apache.camel.util.ObjectHelper;
import java.util.Map;
/**
* A constant (singleton) bean implementation of {@link org.apache.camel.component.bean.BeanTypeHolder}
*/
public class ConstantTypeBeanHolder implements BeanTypeHolder {
private final Class<?> type;
private final BeanInfo beanInfo;
private Map<String, Object> options;
public ConstantTypeBeanHolder(Class<?> type, CamelContext context) {
this(type, new BeanInfo(context, type));
}
public ConstantTypeBeanHolder(Class<?> type, BeanInfo beanInfo) {
ObjectHelper.notNull(type, "type");
ObjectHelper.notNull(beanInfo, "beanInfo");
this.type = type;
this.beanInfo = beanInfo;
}
@Override
public Map<String, Object> getOptions() {
return options;
}
@Override
public void setOptions(Map<String, Object> options) {
this.options = options;
}
/**
* Creates a cached and constant {@link org.apache.camel.component.bean.BeanHolder} from this holder.
*
* @return a new {@link org.apache.camel.component.bean.BeanHolder} that has cached the lookup of the bean.
*/
public ConstantBeanHolder createCacheHolder() throws Exception {
Object bean = getBean(null);
return new ConstantBeanHolder(bean, beanInfo);
}
@Override
public String toString() {
return type.toString();
}
@Override
public Object getBean(Exchange exchange) {
// only create a bean if we have a default no-arg constructor
if (beanInfo.hasPublicNoArgConstructors()) {
Object bean = getBeanInfo().getCamelContext().getInjector().newInstance(type, false);
if (options != null && !options.isEmpty()) {
PropertyBindingSupport.build()
.withRemoveParameters(false)
.withCamelContext(getBeanInfo().getCamelContext())
.withProperties(options)
.withTarget(bean)
.bind();
}
return bean;
} else {
return null;
}
}
@Override
public Processor getProcessor() {
return null;
}
@Override
public boolean supportProcessor() {
return false;
}
@Override
public BeanInfo getBeanInfo() {
return beanInfo;
}
@Override
public BeanInfo getBeanInfo(Object bean) {
return null;
}
@Override
public Class<?> getType() {
return type;
}
}

View File

@ -1,159 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.BeanScope;
import org.apache.camel.CamelContext;
import org.apache.camel.Processor;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.spi.BeanProcessorFactory;
import org.apache.camel.spi.annotations.JdkService;
import org.apache.camel.support.CamelContextHelper;
import org.apache.camel.util.ObjectHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
@JdkService(BeanProcessorFactory.FACTORY)
public final class DefaultBeanProcessorFactory implements BeanProcessorFactory {
private static final Logger LOG = LoggerFactory.getLogger(DefaultBeanProcessorFactory.class);
public DefaultBeanProcessorFactory() {
}
@Override
public Processor createBeanProcessor(CamelContext camelContext, Object bean, Method method) throws Exception {
BeanInfo info = new BeanInfo(camelContext, method);
return new BeanProcessor(bean, info);
}
@Override
public Processor createBeanProcessor(CamelContext camelContext, Object bean, String beanType, Class<?> beanClass, String ref,
String method, BeanScope scope) throws Exception {
BeanProcessor answer;
Class<?> clazz = bean != null ? bean.getClass() : null;
BeanHolder beanHolder;
if (ObjectHelper.isNotEmpty(ref)) {
if (scope == BeanScope.Singleton) {
// cache the registry lookup which avoids repeat lookup in the registry
beanHolder = new RegistryBean(camelContext, ref).createCacheHolder();
// bean holder will check if the bean exists
bean = beanHolder.getBean(null);
} else {
// we do not cache so we invoke on-demand
beanHolder = new RegistryBean(camelContext, ref);
}
if (scope == BeanScope.Request) {
// wrap in registry scoped holder
beanHolder = new RequestBeanHolder(beanHolder);
}
answer = new BeanProcessor(beanHolder);
} else {
if (bean == null) {
if (beanType == null && beanClass == null) {
throw new IllegalArgumentException("bean, ref or beanType must be provided");
}
// the clazz is either from beanType or beanClass
if (beanType != null) {
try {
clazz = camelContext.getClassResolver().resolveMandatoryClass(beanType);
} catch (ClassNotFoundException e) {
throw RuntimeCamelException.wrapRuntimeCamelException(e);
}
} else {
clazz = beanClass;
}
// attempt to create bean using injector which supports auto-wiring
if (scope == BeanScope.Singleton && camelContext.getInjector().supportsAutoWiring()) {
try {
LOG.debug("Attempting to create new bean instance from class: {} via auto-wiring enabled", clazz);
bean = CamelContextHelper.newInstance(camelContext, clazz);
} catch (Throwable e) {
LOG.debug("Error creating new bean instance from class: " + clazz + ". This exception is ignored", e);
}
}
// create a bean if there is a default public no-arg constructor
if (bean == null && scope == BeanScope.Singleton && ObjectHelper.hasDefaultPublicNoArgConstructor(clazz)) {
LOG.debug("Class has default no-arg constructor so creating a new bean instance: {}", clazz);
bean = CamelContextHelper.newInstance(camelContext, clazz);
ObjectHelper.notNull(bean, "bean", this);
}
}
// validate the bean type is not from java so you by mistake think its a reference
// to a bean name but the String is being invoke instead
if (bean instanceof String) {
throw new IllegalArgumentException("The bean instance is a java.lang.String type: " + bean
+ ". We suppose you want to refer to a bean instance by its id instead. Please use ref.");
}
// the holder should either be bean or type based
if (bean != null) {
beanHolder = new ConstantBeanHolder(bean, camelContext);
} else {
if (scope == BeanScope.Singleton && ObjectHelper.hasDefaultPublicNoArgConstructor(clazz)) {
// we can only cache if we can create an instance of the bean, and for that we need a public constructor
beanHolder = new ConstantTypeBeanHolder(clazz, camelContext).createCacheHolder();
} else {
if (ObjectHelper.hasDefaultPublicNoArgConstructor(clazz)) {
beanHolder = new ConstantTypeBeanHolder(clazz, camelContext);
} else {
// this is only for invoking static methods on the bean
beanHolder = new ConstantStaticTypeBeanHolder(clazz, camelContext);
}
}
}
if (scope == BeanScope.Request) {
// wrap in registry scoped holder
beanHolder = new RequestBeanHolder(beanHolder);
}
answer = new BeanProcessor(beanHolder);
}
// check for method exists
if (method != null) {
answer.setMethod(method);
// check there is a method with the given name, and leverage BeanInfo for that
// which we only do if we are caching the bean as otherwise we will create a bean instance for this check
// which we only want to do if we cache the bean
if (scope == BeanScope.Singleton) {
BeanInfo beanInfo = beanHolder.getBeanInfo();
if (bean != null) {
// there is a bean instance, so check for any methods
if (!beanInfo.hasMethod(method)) {
throw RuntimeCamelException.wrapRuntimeCamelException(new MethodNotFoundException(null, bean, method));
}
} else if (clazz != null) {
// there is no bean instance, so check for static methods only
if (!beanInfo.hasStaticMethod(method)) {
throw RuntimeCamelException.wrapRuntimeCamelException(new MethodNotFoundException(null, clazz, method, true));
}
}
}
}
return answer;
}
}

View File

@ -1,34 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.Endpoint;
import org.apache.camel.spi.BeanProxyFactory;
import org.apache.camel.spi.annotations.JdkService;
@JdkService(BeanProxyFactory.FACTORY)
public final class DefaultBeanProxyFactory implements BeanProxyFactory {
public DefaultBeanProxyFactory() {
}
@SafeVarargs
@Override
public final <T> T createProxy(Endpoint endpoint, boolean binding, Class<T>... interfaceClasses) throws Exception {
return ProxyHelper.createProxy(endpoint, binding, interfaceClasses);
}
}

View File

@ -1,54 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.*;
import org.apache.camel.spi.Registry;
import org.apache.camel.support.builder.ExpressionBuilder;
import java.util.HashMap;
import java.util.Map;
/**
* Represents the strategy used to figure out how to map a message exchange to a POJO method invocation
*/
public final class DefaultParameterMappingStrategy implements ParameterMappingStrategy {
public static final DefaultParameterMappingStrategy INSTANCE = new DefaultParameterMappingStrategy();
private static final Map<Class<?>, Expression> MAP = new HashMap<>(6);
static {
MAP.put(Exchange.class, ExpressionBuilder.exchangeExpression());
MAP.put(Message.class, ExpressionBuilder.inMessageExpression());
MAP.put(Exception.class, ExpressionBuilder.exchangeExceptionExpression());
MAP.put(TypeConverter.class, ExpressionBuilder.typeConverterExpression());
MAP.put(Registry.class, ExpressionBuilder.registryExpression());
MAP.put(CamelContext.class, ExpressionBuilder.camelContextExpression());
}
;
private DefaultParameterMappingStrategy() {
}
@Override
public Expression getDefaultParameterTypeExpression(Class<?> parameterType) {
return MAP.get(parameterType);
}
}

View File

@ -1,68 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import java.io.Serializable;
import java.lang.reflect.Method;
/**
* Represents a {@link Serializable} version of a {@link Method}
*/
public class MethodBean implements Serializable {
private static final long serialVersionUID = -789408217201706532L;
private String name;
private Class<?> type;
private Class<?>[] parameterTypes;
public MethodBean() {
}
public MethodBean(Method method) {
this.name = method.getName();
this.type = method.getDeclaringClass();
this.parameterTypes = method.getParameterTypes();
}
public Method getMethod() throws NoSuchMethodException {
return type.getMethod(name, parameterTypes);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Class<?>[] getParameterTypes() {
return parameterTypes;
}
public void setParameterTypes(Class<?>[] parameterTypes) {
this.parameterTypes = parameterTypes;
}
public Class<?> getType() {
return type;
}
public void setType(Class<?> type) {
this.type = type;
}
}

View File

@ -1,755 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.*;
import org.apache.camel.component.bean.BeanHelper;
import org.apache.camel.support.*;
import org.apache.camel.support.service.ServiceHelper;
import org.apache.camel.util.StringHelper;
import org.apache.camel.util.StringQuoteHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionStage;
import static org.apache.camel.util.ObjectHelper.asList;
import static org.apache.camel.util.ObjectHelper.asString;
/**
* Information about a method to be used for invocation.
*/
public class MethodInfo {
private static final Logger LOG = LoggerFactory.getLogger(MethodInfo.class);
private CamelContext camelContext;
private Class<?> type;
private Method method;
private final List<ParameterInfo> parameters;
private final List<ParameterInfo> bodyParameters;
private final boolean hasCustomAnnotation;
private final boolean hasHandlerAnnotation;
private Expression parametersExpression;
private ExchangePattern pattern = ExchangePattern.InOut;
private AsyncProcessor recipientList;
private AsyncProcessor routingSlip;
private AsyncProcessor dynamicRouter;
/**
* Adapter to invoke the method which has been annotated with the @DynamicRouter
*/
private final class DynamicRouterExpression extends ExpressionAdapter {
private final Object pojo;
private DynamicRouterExpression(Object pojo) {
this.pojo = pojo;
}
@Override
public Object evaluate(Exchange exchange) {
// evaluate arguments on each invocation as the parameters can have changed/updated since last invocation
final Object[] arguments = parametersExpression.evaluate(exchange, Object[].class);
try {
return invoke(method, pojo, arguments, exchange);
} catch (Exception e) {
throw RuntimeCamelException.wrapRuntimeCamelException(e);
}
}
@Override
public String toString() {
return "DynamicRouter[invoking: " + method + " on bean: " + pojo + "]";
}
}
public MethodInfo(CamelContext camelContext, Class<?> type, Method method, List<ParameterInfo> parameters, List<ParameterInfo> bodyParameters,
boolean hasCustomAnnotation, boolean hasHandlerAnnotation) {
this.camelContext = camelContext;
this.type = type;
this.method = method;
this.parameters = parameters;
this.bodyParameters = bodyParameters;
this.hasCustomAnnotation = hasCustomAnnotation;
this.hasHandlerAnnotation = hasHandlerAnnotation;
this.parametersExpression = createParametersExpression();
Map<Class<?>, Annotation> collectedMethodAnnotation = collectMethodAnnotations(type, method);
Pattern oneway = findOneWayAnnotation(method);
if (oneway != null) {
pattern = oneway.value();
}
org.apache.camel.RoutingSlip routingSlipAnnotation =
(org.apache.camel.RoutingSlip) collectedMethodAnnotation.get(org.apache.camel.RoutingSlip.class);
if (routingSlipAnnotation != null) {
routingSlip = camelContext.adapt(ExtendedCamelContext.class).getAnnotationBasedProcessorFactory().createRoutingSlip(camelContext, routingSlipAnnotation);
// add created routingSlip as a service so we have its lifecycle managed
try {
camelContext.addService(routingSlip);
} catch (Exception e) {
throw RuntimeCamelException.wrapRuntimeCamelException(e);
}
}
org.apache.camel.DynamicRouter dynamicRouterAnnotation =
(org.apache.camel.DynamicRouter) collectedMethodAnnotation.get(org.apache.camel.DynamicRouter.class);
if (dynamicRouterAnnotation != null) {
dynamicRouter = camelContext.adapt(ExtendedCamelContext.class).getAnnotationBasedProcessorFactory().createDynamicRouter(camelContext, dynamicRouterAnnotation);
// add created dynamicRouter as a service so we have its lifecycle managed
try {
camelContext.addService(dynamicRouter);
} catch (Exception e) {
throw RuntimeCamelException.wrapRuntimeCamelException(e);
}
}
org.apache.camel.RecipientList recipientListAnnotation =
(org.apache.camel.RecipientList) collectedMethodAnnotation.get(org.apache.camel.RecipientList.class);
if (recipientListAnnotation != null) {
recipientList = camelContext.adapt(ExtendedCamelContext.class).getAnnotationBasedProcessorFactory().createRecipientList(camelContext, recipientListAnnotation);
// add created recipientList as a service so we have its lifecycle managed
try {
camelContext.addService(recipientList);
} catch (Exception e) {
throw RuntimeCamelException.wrapRuntimeCamelException(e);
}
}
}
private Map<Class<?>, Annotation> collectMethodAnnotations(Class<?> c, Method method) {
Map<Class<?>, Annotation> annotations = new HashMap<>();
collectMethodAnnotations(c, method, annotations);
return annotations;
}
private void collectMethodAnnotations(Class<?> c, Method method, Map<Class<?>, Annotation> annotations) {
for (Class<?> i : c.getInterfaces()) {
collectMethodAnnotations(i, method, annotations);
}
if (!c.isInterface() && c.getSuperclass() != null) {
collectMethodAnnotations(c.getSuperclass(), method, annotations);
}
// make sure the sub class can override the definition
try {
Annotation[] ma = c.getDeclaredMethod(method.getName(), method.getParameterTypes()).getAnnotations();
for (Annotation a : ma) {
annotations.put(a.annotationType(), a);
}
} catch (SecurityException | NoSuchMethodException e) {
// do nothing here
}
}
@Override
public String toString() {
return method.toString();
}
public MethodInvocation createMethodInvocation(final Object pojo, boolean hasParameters, final Exchange exchange) {
final Object[] arguments;
if (hasParameters) {
arguments = parametersExpression.evaluate(exchange, Object[].class);
} else {
arguments = null;
}
return new MethodInvocation() {
public Method getMethod() {
return method;
}
public Object[] getArguments() {
return arguments;
}
public boolean proceed(AsyncCallback callback) {
try {
// reset cached streams so they can be read again
MessageHelper.resetStreamCache(exchange.getIn());
return doProceed(callback);
} catch (InvocationTargetException e) {
exchange.setException(e.getTargetException());
callback.done(true);
return true;
} catch (Throwable e) {
exchange.setException(e);
callback.done(true);
return true;
}
}
private boolean doProceed(AsyncCallback callback) throws Exception {
// dynamic router should be invoked beforehand
if (dynamicRouter != null) {
if (!ServiceHelper.isStarted(dynamicRouter)) {
ServiceHelper.startService(dynamicRouter);
}
// TODO: Maybe use a new constant than EVALUATE_EXPRESSION_RESULT
// use a expression which invokes the method to be used by dynamic router
Expression expression = new DynamicRouterExpression(pojo);
exchange.setProperty(Exchange.EVALUATE_EXPRESSION_RESULT, expression);
return dynamicRouter.process(exchange, callback);
}
// invoke pojo
if (LOG.isTraceEnabled()) {
LOG.trace(">>>> invoking: {} on bean: {} with arguments: {} for exchange: {}", method, pojo, asString(arguments), exchange);
}
Object result = invoke(method, pojo, arguments, exchange);
// the method may be a closure or chained method returning a callable which should be called
if (result instanceof Callable) {
LOG.trace("Method returned Callback which will be called: {}", result);
Object callableResult = ((Callable) result).call();
if (callableResult != null) {
result = callableResult;
} else {
// if callable returned null we should not change the body
result = Void.TYPE;
}
}
if (recipientList != null) {
// ensure its started
if (!ServiceHelper.isStarted(recipientList)) {
ServiceHelper.startService(recipientList);
}
exchange.setProperty(Exchange.EVALUATE_EXPRESSION_RESULT, result);
return recipientList.process(exchange, callback);
}
if (routingSlip != null) {
if (!ServiceHelper.isStarted(routingSlip)) {
ServiceHelper.startService(routingSlip);
}
exchange.setProperty(Exchange.EVALUATE_EXPRESSION_RESULT, result);
return routingSlip.process(exchange, callback);
}
//If it's Java 8 async result
if (CompletionStage.class.isAssignableFrom(method.getReturnType())) {
CompletionStage<?> completionStage = (CompletionStage<?>) result;
completionStage
.whenComplete((resultObject, e) -> {
if (e != null) {
exchange.setException(e);
} else if (resultObject != null) {
fillResult(exchange, resultObject);
}
callback.done(false);
});
return false;
}
// if the method returns something then set the value returned on the Exchange
if (result != Void.TYPE && !method.getReturnType().equals(Void.TYPE)) {
fillResult(exchange, result);
}
// we did not use any of the eips, but just invoked the bean
// so notify the callback we are done synchronously
callback.done(true);
return true;
}
public Object getThis() {
return pojo;
}
public AccessibleObject getStaticPart() {
return method;
}
};
}
private void fillResult(Exchange exchange, Object result) {
LOG.trace("Setting bean invocation result : {}", result);
// the bean component forces OUT if the MEP is OUT capable
boolean out = exchange.hasOut() || ExchangeHelper.isOutCapable(exchange);
Message old;
if (out) {
old = exchange.getOut();
// propagate headers
exchange.getOut().getHeaders().putAll(exchange.getIn().getHeaders());
} else {
old = exchange.getIn();
}
// create a new message container so we do not drag specialized message objects along
// but that is only needed if the old message is a specialized message
boolean copyNeeded = !(old.getClass().equals(DefaultMessage.class));
if (copyNeeded) {
Message msg = new DefaultMessage(exchange.getContext());
msg.copyFromWithNewBody(old, result);
// replace message on exchange
ExchangeHelper.replaceMessage(exchange, msg, false);
} else {
// no copy needed so set replace value directly
old.setBody(result);
}
}
public Class<?> getType() {
return type;
}
public Method getMethod() {
return method;
}
/**
* Returns the {@link org.apache.camel.ExchangePattern} that should be used when invoking this method. This value
* defaults to {@link org.apache.camel.ExchangePattern#InOut} unless some {@link org.apache.camel.Pattern} annotation is used
* to override the message exchange pattern.
*
* @return the exchange pattern to use for invoking this method.
*/
public ExchangePattern getPattern() {
return pattern;
}
public Expression getParametersExpression() {
return parametersExpression;
}
public List<ParameterInfo> getBodyParameters() {
return bodyParameters;
}
public Class<?> getBodyParameterType() {
if (bodyParameters.isEmpty()) {
return null;
}
ParameterInfo parameterInfo = bodyParameters.get(0);
return parameterInfo.getType();
}
public boolean bodyParameterMatches(Class<?> bodyType) {
Class<?> actualType = getBodyParameterType();
return actualType != null && org.apache.camel.util.ObjectHelper.isAssignableFrom(bodyType, actualType);
}
public List<ParameterInfo> getParameters() {
return parameters;
}
public boolean hasBodyParameter() {
return !bodyParameters.isEmpty();
}
public boolean hasCustomAnnotation() {
return hasCustomAnnotation;
}
public boolean hasHandlerAnnotation() {
return hasHandlerAnnotation;
}
public boolean hasParameters() {
return !parameters.isEmpty();
}
public boolean isReturnTypeVoid() {
return method.getReturnType().getName().equals("void");
}
public boolean isStaticMethod() {
return Modifier.isStatic(method.getModifiers());
}
/**
* Returns true if this method is covariant with the specified method
* (this method may above or below the specified method in the class hierarchy)
*/
public boolean isCovariantWith(MethodInfo method) {
return
method.getMethod().getName().equals(this.getMethod().getName())
&& (method.getMethod().getReturnType().isAssignableFrom(this.getMethod().getReturnType())
|| this.getMethod().getReturnType().isAssignableFrom(method.getMethod().getReturnType()))
&& Arrays.deepEquals(method.getMethod().getParameterTypes(), this.getMethod().getParameterTypes());
}
protected Object invoke(Method mth, Object pojo, Object[] arguments, Exchange exchange) throws InvocationTargetException {
try {
return ObjectHelper.invokeMethodSafe(mth, pojo, arguments);
} catch (IllegalAccessException e) {
throw new RuntimeExchangeException("IllegalAccessException occurred invoking method: " + mth + " using arguments: " + asList(arguments), exchange, e);
} catch (IllegalArgumentException e) {
throw new RuntimeExchangeException("IllegalArgumentException occurred invoking method: " + mth + " using arguments: " + asList(arguments), exchange, e);
}
}
protected Expression[] createParameterExpressions() {
final int size = parameters.size();
LOG.trace("Creating parameters expression for {} parameters", size);
final Expression[] expressions = new Expression[size];
for (int i = 0; i < size; i++) {
Expression parameterExpression = parameters.get(i).getExpression();
expressions[i] = parameterExpression;
LOG.trace("Parameter #{} has expression: {}", i, parameterExpression);
}
return expressions;
}
protected Expression createParametersExpression() {
return new ParameterExpression(createParameterExpressions());
}
/**
* Finds the oneway annotation in priority order; look for method level annotations first, then the class level annotations,
* then super class annotations then interface annotations
*
* @param method the method on which to search
* @return the first matching annotation or none if it is not available
*/
protected Pattern findOneWayAnnotation(Method method) {
Pattern answer = getPatternAnnotation(method);
if (answer == null) {
Class<?> type = method.getDeclaringClass();
// create the search order of types to scan
List<Class<?>> typesToSearch = new ArrayList<>();
addTypeAndSuperTypes(type, typesToSearch);
Class<?>[] interfaces = type.getInterfaces();
for (Class<?> anInterface : interfaces) {
addTypeAndSuperTypes(anInterface, typesToSearch);
}
// now let's scan for a type which the current declared class overloads
answer = findOneWayAnnotationOnMethod(typesToSearch, method);
if (answer == null) {
answer = findOneWayAnnotation(typesToSearch);
}
}
return answer;
}
/**
* Returns the pattern annotation on the given annotated element; either as a direct annotation or
* on an annotation which is also annotated
*
* @param annotatedElement the element to look for the annotation
* @return the first matching annotation or null if none could be found
*/
protected Pattern getPatternAnnotation(AnnotatedElement annotatedElement) {
return getPatternAnnotation(annotatedElement, 2);
}
/**
* Returns the pattern annotation on the given annotated element; either as a direct annotation or
* on an annotation which is also annotated
*
* @param annotatedElement the element to look for the annotation
* @param depth the current depth
* @return the first matching annotation or null if none could be found
*/
protected Pattern getPatternAnnotation(AnnotatedElement annotatedElement, int depth) {
Pattern answer = annotatedElement.getAnnotation(Pattern.class);
int nextDepth = depth - 1;
if (nextDepth > 0) {
// look at all the annotations to see if any of those are annotated
Annotation[] annotations = annotatedElement.getAnnotations();
for (Annotation annotation : annotations) {
Class<? extends Annotation> annotationType = annotation.annotationType();
if (annotation instanceof Pattern || annotationType.equals(annotatedElement)) {
continue;
} else {
Pattern another = getPatternAnnotation(annotationType, nextDepth);
if (pattern != null) {
if (answer == null) {
answer = another;
} else {
LOG.warn("Duplicate pattern annotation: {} found on annotation: {} which will be ignored", another, annotation);
}
}
}
}
}
return answer;
}
/**
* Adds the current class and all of its base classes (apart from {@link Object} to the given list
*/
protected void addTypeAndSuperTypes(Class<?> type, List<Class<?>> result) {
for (Class<?> t = type; t != null && t != Object.class; t = t.getSuperclass()) {
result.add(t);
}
}
/**
* Finds the first annotation on the base methods defined in the list of classes
*/
protected Pattern findOneWayAnnotationOnMethod(List<Class<?>> classes, Method method) {
for (Class<?> type : classes) {
try {
Method definedMethod = type.getMethod(method.getName(), method.getParameterTypes());
Pattern answer = getPatternAnnotation(definedMethod);
if (answer != null) {
return answer;
}
} catch (NoSuchMethodException e) {
// ignore
}
}
return null;
}
/**
* Finds the first annotation on the given list of classes
*/
protected Pattern findOneWayAnnotation(List<Class<?>> classes) {
for (Class<?> type : classes) {
Pattern answer = getPatternAnnotation(type);
if (answer != null) {
return answer;
}
}
return null;
}
protected boolean hasExceptionParameter() {
for (ParameterInfo parameter : parameters) {
if (Exception.class.isAssignableFrom(parameter.getType())) {
return true;
}
}
return false;
}
/**
* Expression to evaluate the bean parameter parameters and provide the correct values when the method is invoked.
*/
private final class ParameterExpression implements Expression {
private final Expression[] expressions;
ParameterExpression(Expression[] expressions) {
this.expressions = expressions;
}
@Override
@SuppressWarnings("unchecked")
public <T> T evaluate(Exchange exchange, Class<T> type) {
Object body = exchange.getIn().getBody();
// if there was an explicit method name to invoke, then we should support using
// any provided parameter values in the method name
String methodName = exchange.getIn().getHeader(Exchange.BEAN_METHOD_NAME, String.class);
// the parameter values is between the parenthesis
String methodParameters = StringHelper.betweenOuterPair(methodName, '(', ')');
// use an iterator to walk the parameter values
Iterator<?> it = null;
if (methodParameters != null) {
// split the parameters safely separated by comma, but beware that we can have
// quoted parameters which contains comma as well, so do a safe quote split
String[] parameters = StringQuoteHelper.splitSafeQuote(methodParameters, ',', true);
it = ObjectHelper.createIterator(parameters, ",", true);
}
// remove headers as they should not be propagated
// we need to do this before the expressions gets evaluated as it may contain
// a @Bean expression which would by mistake read these headers. So the headers
// must be removed at this point of time
if (methodName != null) {
exchange.getIn().removeHeader(Exchange.BEAN_METHOD_NAME);
}
Object[] answer = evaluateParameterExpressions(exchange, body, it);
return (T) answer;
}
/**
* Evaluates all the parameter expressions
*/
private Object[] evaluateParameterExpressions(Exchange exchange, Object body, Iterator<?> it) {
Object[] answer = new Object[expressions.length];
for (int i = 0; i < expressions.length; i++) {
if (body instanceof StreamCache) {
// need to reset stream cache for each expression as you may access the message body in multiple parameters
((StreamCache) body).reset();
}
// grab the parameter value for the given index
Object parameterValue = it != null && it.hasNext() ? it.next() : null;
// and the expected parameter type
Class<?> parameterType = parameters.get(i).getType();
// the value for the parameter to use
Object value = null;
// prefer to use parameter value if given, as they override any bean parameter binding
// we should skip * as its a type placeholder to indicate any type
if (parameterValue != null && !parameterValue.equals("*")) {
// evaluate the parameter value binding
value = evaluateParameterValue(exchange, i, parameterValue, parameterType);
}
// use bean parameter binding, if still no value
Expression expression = expressions[i];
if (value == null && expression != null) {
value = evaluateParameterBinding(exchange, expression, i, parameterType);
}
// remember the value to use
if (value != Void.TYPE) {
answer[i] = value;
}
}
return answer;
}
/**
* Evaluate using parameter values where the values can be provided in the method name syntax.
* <p/>
* This methods returns accordingly:
* <ul>
* <li><tt>null</tt> - if not a parameter value</li>
* <li><tt>Void.TYPE</tt> - if an explicit null, forcing Camel to pass in <tt>null</tt> for that given parameter</li>
* <li>a non <tt>null</tt> value - if the parameter was a parameter value, and to be used</li>
* </ul>
*
* @since 2.9
*/
private Object evaluateParameterValue(Exchange exchange, int index, Object parameterValue, Class<?> parameterType) {
Object answer = null;
// convert the parameter value to a String
String exp = exchange.getContext().getTypeConverter().convertTo(String.class, exchange, parameterValue);
if (exp != null) {
// check if its a valid parameter value
boolean valid = org.apache.camel.component.bean.BeanHelper.isValidParameterValue(exp);
if (!valid) {
// it may be a parameter type instead, and if so, then we should return null,
// as this method is only for evaluating parameter values
Boolean isClass = org.apache.camel.component.bean.BeanHelper.isAssignableToExpectedType(exchange.getContext().getClassResolver(), exp, parameterType);
// the method will return a non null value if exp is a class
if (isClass != null) {
return null;
}
}
// use simple language to evaluate the expression, as it may use the simple language to refer to message body, headers etc.
Expression expression = null;
try {
expression = exchange.getContext().resolveLanguage("simple").createExpression(exp);
parameterValue = expression.evaluate(exchange, Object.class);
// use "null" to indicate the expression returned a null value which is a valid response we need to honor
if (parameterValue == null) {
parameterValue = "null";
}
} catch (Exception e) {
throw new ExpressionEvaluationException(expression, "Cannot create/evaluate simple expression: " + exp
+ " to be bound to parameter at index: " + index + " on method: " + getMethod(), exchange, e);
}
// special for explicit null parameter values (as end users can explicit indicate they want null as parameter)
// see method javadoc for details
if ("null".equals(parameterValue)) {
return Void.TYPE;
}
// the parameter value may match the expected type, then we use it as-is
if (parameterType.isAssignableFrom(parameterValue.getClass())) {
valid = true;
} else {
// the parameter value was not already valid, but since the simple language have evaluated the expression
// which may change the parameterValue, so we have to check it again to see if its now valid
exp = exchange.getContext().getTypeConverter().tryConvertTo(String.class, parameterValue);
// String values from the simple language is always valid
if (!valid) {
// re validate if the parameter was not valid the first time (String values should be accepted)
valid = parameterValue instanceof String || BeanHelper.isValidParameterValue(exp);
}
}
if (valid) {
// we need to unquote String parameters, as the enclosing quotes is there to denote a parameter value
if (parameterValue instanceof String) {
parameterValue = StringHelper.removeLeadingAndEndingQuotes((String) parameterValue);
}
if (parameterValue != null) {
try {
// its a valid parameter value, so convert it to the expected type of the parameter
answer = exchange.getContext().getTypeConverter().mandatoryConvertTo(parameterType, exchange, parameterValue);
if (LOG.isTraceEnabled()) {
LOG.trace("Parameter #{} evaluated as: {} type: {}", index, answer, org.apache.camel.util.ObjectHelper.type(answer));
}
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Cannot convert from type: {} to type: {} for parameter #{}", org.apache.camel.util.ObjectHelper.type(parameterValue), parameterType, index);
}
throw new ParameterBindingException(e, method, index, parameterType, parameterValue);
}
}
}
}
return answer;
}
/**
* Evaluate using classic parameter binding using the pre compute expression
*/
private Object evaluateParameterBinding(Exchange exchange, Expression expression, int index, Class<?> parameterType) {
Object answer = null;
// use object first to avoid type conversion so we know if there is a value or not
Object result = expression.evaluate(exchange, Object.class);
if (result != null) {
try {
if (parameterType.isInstance(result)) {
// optimize if the value is already the same type
answer = result;
} else {
// we got a value now try to convert it to the expected type
answer = exchange.getContext().getTypeConverter().mandatoryConvertTo(parameterType, result);
}
if (LOG.isTraceEnabled()) {
LOG.trace("Parameter #{} evaluated as: {} type: {}", index, answer, org.apache.camel.util.ObjectHelper.type(answer));
}
} catch (NoTypeConversionAvailableException e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Cannot convert from type: {} to type: {} for parameter #{}", org.apache.camel.util.ObjectHelper.type(result), parameterType, index);
}
throw new ParameterBindingException(e, method, index, parameterType, result);
}
} else {
LOG.trace("Parameter #{} evaluated as null", index);
}
return answer;
}
@Override
public String toString() {
return "ParametersExpression: " + Arrays.asList(expressions);
}
}
}

View File

@ -1,89 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.CamelContext;
import org.apache.camel.support.LRUCacheFactory;
import java.lang.reflect.Method;
import java.util.Map;
/**
* Represents a cache of {@link org.apache.camel.component.bean.MethodInfo} objects to avoid the expense of introspection for each
* invocation of a method via a proxy.
*/
public class MethodInfoCache {
private final CamelContext camelContext;
private Map<Method, MethodInfo> methodCache;
private Map<Class<?>, BeanInfo> classCache;
public MethodInfoCache(CamelContext camelContext) {
this(camelContext, 1000, 10000);
}
public MethodInfoCache(CamelContext camelContext, int classCacheSize, int methodCacheSize) {
this(camelContext, createClassCache(classCacheSize), createMethodCache(methodCacheSize));
}
public MethodInfoCache(CamelContext camelContext, Map<Class<?>, BeanInfo> classCache, Map<Method, MethodInfo> methodCache) {
this.camelContext = camelContext;
this.classCache = classCache;
this.methodCache = methodCache;
}
public synchronized MethodInfo getMethodInfo(Method method) {
MethodInfo answer = methodCache.get(method);
if (answer == null) {
answer = createMethodInfo(method);
methodCache.put(method, answer);
}
return answer;
}
protected MethodInfo createMethodInfo(Method method) {
Class<?> declaringClass = method.getDeclaringClass();
BeanInfo info = getBeanInfo(declaringClass);
return info.getMethodInfo(method);
}
protected synchronized BeanInfo getBeanInfo(Class<?> declaringClass) {
BeanInfo beanInfo = classCache.get(declaringClass);
if (beanInfo == null) {
beanInfo = createBeanInfo(declaringClass);
classCache.put(declaringClass, beanInfo);
}
return beanInfo;
}
protected BeanInfo createBeanInfo(Class<?> declaringClass) {
return new BeanInfo(camelContext, declaringClass);
}
@SuppressWarnings("unchecked")
protected static <K, V> Map<K, V> createLruCache(int size) {
// use a soft cache
return LRUCacheFactory.newLRUSoftCache(size);
}
private static Map<Class<?>, BeanInfo> createClassCache(int size) {
return createLruCache(size);
}
private static Map<Method, MethodInfo> createMethodCache(int size) {
return createLruCache(size);
}
}

View File

@ -1,44 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.AsyncCallback;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
/**
* Information used by Camel to perform method invocation.
*/
public interface MethodInvocation {
Method getMethod();
Object[] getArguments();
/**
* Proceed and invokes the method.
*
* @param callback the callback
* @return see {@link org.apache.camel.AsyncProcessor#process(org.apache.camel.Exchange, org.apache.camel.AsyncCallback)}
*/
boolean proceed(AsyncCallback callback);
Object getThis();
AccessibleObject getStaticPart();
}

View File

@ -1,65 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.Exchange;
import org.apache.camel.RuntimeExchangeException;
import org.apache.camel.util.ObjectHelper;
public class MethodNotFoundException extends RuntimeExchangeException {
private final Object bean;
private final String methodName;
public MethodNotFoundException(Exchange exchange, Object pojo, String methodName) {
super("Method with name: " + methodName + " not found on bean: " + pojo + " of type: " + ObjectHelper.className(pojo), exchange);
this.methodName = methodName;
this.bean = pojo;
}
public MethodNotFoundException(Exchange exchange, Object pojo, String methodName, String postfix) {
super("Method with name: " + methodName + " " + postfix + " not found on bean: " + pojo + " of type: " + ObjectHelper.className(pojo), exchange);
this.methodName = methodName;
this.bean = pojo;
}
public MethodNotFoundException(Exchange exchange, Class<?> type, String methodName, boolean isStaticMethod) {
super((isStaticMethod ? "Static method" : "Method") + " with name: " + methodName + " not found on class: " + ObjectHelper.name(type), exchange);
this.methodName = methodName;
this.bean = null;
}
public MethodNotFoundException(Object pojo, String methodName, Throwable cause) {
super("Method with name: " + methodName + " not found on bean: " + pojo + " of type:" + ObjectHelper.className(pojo), null, cause);
this.methodName = methodName;
this.bean = pojo;
}
public MethodNotFoundException(Class<?> type, String methodName, Throwable cause) {
super("Method with name: " + methodName + " not found on class: " + ObjectHelper.className(type), null, cause);
this.methodName = methodName;
this.bean = null;
}
public String getMethodName() {
return methodName;
}
public Object getBean() {
return bean;
}
}

View File

@ -1,84 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.util.ObjectHelper;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* This class aims at retaining the right methods while parsing a given
* {@link java.lang.Class}.
*/
class MethodsFilter {
private final List<Method> methods = new ArrayList<>();
private final Class<?> inheritingClass;
/**
* Creates a <code>MethodsFilter</code> for a given {@link java.lang.Class}.
*
* @param clazz The {@link java.lang.Class} whose methods are to be
* filtered.
*/
public MethodsFilter(Class<?> clazz) {
this.inheritingClass = clazz;
}
/**
* Retains methods, preferring those from public classes in case of
* overrides.
*
* @param proposedMethod The method proposed to the filter.
*/
void filterMethod(Method proposedMethod) {
if (proposedMethod.isBridge()) {
return;
}
for (int i = 0; i < methods.size(); i++) {
Method alreadyRegistered = methods.get(i);
if (Modifier.isPublic(proposedMethod.getDeclaringClass().getModifiers())) {
boolean overridden = ObjectHelper.isOverridingMethod(inheritingClass, proposedMethod, alreadyRegistered, false);
boolean overridding = ObjectHelper.isOverridingMethod(inheritingClass, alreadyRegistered, proposedMethod, false);
boolean registeredMethodIsPublic = Modifier.isPublic(alreadyRegistered.getDeclaringClass().getModifiers());
if (overridden && !registeredMethodIsPublic) {
// Retain the overridden method from a public class
methods.set(i, proposedMethod);
return;
} else if (overridding) {
// Retain the override from a public class
methods.set(i, proposedMethod);
return;
}
}
}
methods.add(proposedMethod);
}
List<Method> asReadOnlyList() {
return Collections.unmodifiableList(methods);
}
}

View File

@ -1,59 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.util.ObjectHelper;
import java.lang.reflect.Method;
public class ParameterBindingException extends RuntimeCamelException {
private final Method method;
private final int index;
private final Class<?> parameterType;
private final Object parameterValue;
public ParameterBindingException(Throwable cause, Method method, int index, Class<?> parameterType, Object parameterValue) {
super(createMessage(method, index, parameterType, parameterValue), cause);
this.method = method;
this.index = index;
this.parameterType = parameterType;
this.parameterValue = parameterValue;
}
public Method getMethod() {
return method;
}
public int getIndex() {
return index;
}
public Class<?> getParameterType() {
return parameterType;
}
public Object getParameterValue() {
return parameterValue;
}
private static String createMessage(Method method, int index, Class<?> parameterType, Object parameterValue) {
return "Error during parameter binding on method: " + method + " at parameter #" + index + " with type: " + parameterType
+ " with value type: " + ObjectHelper.type(parameterValue) + " and value: " + parameterValue;
}
}

View File

@ -1,72 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.Expression;
import java.lang.annotation.Annotation;
import java.util.Arrays;
/**
* Parameter information to be used for method invocation.
*/
final class ParameterInfo {
private final int index;
private final Class<?> type;
private final Annotation[] annotations;
private Expression expression;
ParameterInfo(int index, Class<?> type, Annotation[] annotations, Expression expression) {
this.index = index;
this.type = type;
this.annotations = annotations;
this.expression = expression;
}
public Annotation[] getAnnotations() {
return annotations;
}
public Expression getExpression() {
return expression;
}
public int getIndex() {
return index;
}
public Class<?> getType() {
return type;
}
public void setExpression(Expression expression) {
this.expression = expression;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("ParameterInfo");
sb.append("[index=").append(index);
sb.append(", type=").append(type);
sb.append(", annotations=").append(annotations == null ? "null" : Arrays.asList(annotations).toString());
sb.append(", expression=").append(expression);
sb.append(']');
return sb.toString();
}
}

View File

@ -1,34 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.Expression;
/**
* A strategy for creating a default parameter expression for a given type
*/
public interface ParameterMappingStrategy {
/**
* Gets an expression used for evaluation with the current Exchange and its result
* is used as parameter value for the given type
*
* @param parameterType the parameter type
* @return the expression to evaluate as value
*/
Expression getDefaultParameterTypeExpression(Class<?> parameterType);
}

View File

@ -1,51 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.Endpoint;
import org.apache.camel.ExchangePattern;
import org.apache.camel.Producer;
import org.apache.camel.RuntimeCamelException;
import java.lang.reflect.Method;
/**
* Special {@link java.lang.reflect.InvocationHandler} for methods that have only one parameter. This
* parameter is directly sent to as the body of the message. The idea is to use
* that as a very open message format especially when combined with e.g. JAXB
* serialization.
*/
@Deprecated
public class PojoMessageInvocationHandler extends AbstractCamelInvocationHandler {
public PojoMessageInvocationHandler(Endpoint endpoint, Producer producer) {
super(endpoint, producer);
}
@Override
public Object doInvokeProxy(Object proxy, Method method, Object[] args) throws Throwable {
int argsLength = (args == null) ? 0 : args.length;
if (argsLength != 1) {
throw new RuntimeCamelException(String.format("Error creating proxy for %s.%s Number of arguments must be 1 but is %d",
method.getDeclaringClass().getName(),
method.getName(), argsLength));
}
final ExchangePattern pattern = method.getReturnType() != Void.TYPE ? ExchangePattern.InOut : ExchangePattern.InOnly;
return invokeWithBody(method, args[0], pattern);
}
}

View File

@ -1,42 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.Endpoint;
import org.apache.camel.Producer;
import org.apache.camel.support.service.ServiceHelper;
import java.lang.reflect.Proxy;
/**
* Create a dynamic proxy for a given interface and endpoint that sends the parameter object to the endpoint and optionally
* receives a reply. Unlike the ProxyHelper this works only with methods that have only one parameter.
*/
@Deprecated
public final class PojoProxyHelper {
private PojoProxyHelper() {
}
@SuppressWarnings("unchecked")
public static <T> T createProxy(Endpoint endpoint, Class<?>... interfaceClasses) throws Exception {
Producer producer = endpoint.createProducer();
// ensure the producer is started
ServiceHelper.startService(producer);
return (T) Proxy.newProxyInstance(ProxyHelper.getClassLoader(interfaceClasses), interfaceClasses.clone(), new PojoMessageInvocationHandler(endpoint, producer));
}
}

View File

@ -1,122 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.Endpoint;
import org.apache.camel.ExtendedCamelContext;
import org.apache.camel.Producer;
import java.lang.reflect.Proxy;
/**
* A helper class for creating proxies which delegate to Camel
*/
public final class ProxyHelper {
/**
* Utility classes should not have a public constructor.
*/
private ProxyHelper() {
}
/**
* Creates a Proxy which sends the exchange to the endpoint.
*/
@SuppressWarnings("unchecked")
public static <T> T createProxyObject(Endpoint endpoint, boolean binding, Producer producer, ClassLoader classLoader, Class<T>[] interfaces, MethodInfoCache methodCache) {
return (T) Proxy.newProxyInstance(classLoader, interfaces.clone(), new CamelInvocationHandler(endpoint, binding, producer, methodCache));
}
/**
* Creates a Proxy which sends the exchange to the endpoint.
*/
public static <T> T createProxy(Endpoint endpoint, boolean binding, ClassLoader cl, Class<T> interfaceClass, MethodInfoCache methodCache) throws Exception {
return createProxy(endpoint, binding, cl, toArray(interfaceClass), methodCache);
}
/**
* Creates a Proxy which sends the exchange to the endpoint.
*/
public static <T> T createProxy(Endpoint endpoint, boolean binding, ClassLoader cl, Class<T>[] interfaceClasses, MethodInfoCache methodCache) throws Exception {
Producer producer = endpoint.getCamelContext().adapt(ExtendedCamelContext.class).getDeferServiceFactory().createProducer(endpoint);
return createProxyObject(endpoint, binding, producer, cl, interfaceClasses, methodCache);
}
/**
* Creates a Proxy which sends the exchange to the endpoint.
*/
public static <T> T createProxy(Endpoint endpoint, ClassLoader cl, Class<T> interfaceClass) throws Exception {
return createProxy(endpoint, true, cl, toArray(interfaceClass));
}
/**
* Creates a Proxy which sends the exchange to the endpoint.
*/
public static <T> T createProxy(Endpoint endpoint, boolean binding, ClassLoader cl, Class<T>... interfaceClasses) throws Exception {
return createProxy(endpoint, binding, cl, interfaceClasses, createMethodInfoCache(endpoint));
}
/**
* Creates a Proxy which sends the exchange to the endpoint.
*/
public static <T> T createProxy(Endpoint endpoint, Class<T> interfaceClass) throws Exception {
return createProxy(endpoint, true, toArray(interfaceClass));
}
/**
* Creates a Proxy which sends the exchange to the endpoint.
*/
public static <T> T createProxy(Endpoint endpoint, boolean binding, Class<T>... interfaceClasses) throws Exception {
return createProxy(endpoint, binding, getClassLoader(interfaceClasses), interfaceClasses);
}
/**
* Creates a Proxy which sends the exchange to the endpoint.
*/
public static <T> T createProxy(Endpoint endpoint, Producer producer, Class<T> interfaceClass) throws Exception {
return createProxy(endpoint, true, producer, toArray(interfaceClass));
}
/**
* Creates a Proxy which sends the exchange to the endpoint.
*/
public static <T> T createProxy(Endpoint endpoint, boolean binding, Producer producer, Class<T>... interfaceClasses) throws Exception {
return createProxyObject(endpoint, binding, producer, getClassLoader(interfaceClasses), interfaceClasses, createMethodInfoCache(endpoint));
}
/**
* Returns the class loader of the first interface or throws {@link IllegalArgumentException} if there are no interfaces specified
*/
protected static ClassLoader getClassLoader(Class<?>... interfaces) {
if (interfaces == null || interfaces.length < 1) {
throw new IllegalArgumentException("You must provide at least 1 interface class.");
}
return interfaces[0].getClassLoader();
}
protected static MethodInfoCache createMethodInfoCache(Endpoint endpoint) {
return new MethodInfoCache(endpoint.getCamelContext());
}
@SuppressWarnings("unchecked")
private static <T> Class<T>[] toArray(Class<T> interfaceClass) {
// this method and it's usage is introduced to avoid compiler warnings
// about the generic Class arrays in the case we've got only one single
// Class to build a Proxy for
return new Class[]{interfaceClass};
}
}

View File

@ -1,186 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.NoSuchBeanException;
import org.apache.camel.Processor;
import org.apache.camel.spi.Registry;
import org.apache.camel.support.PropertyBindingSupport;
import java.util.Map;
/**
* An implementation of a {@link org.apache.camel.component.bean.BeanHolder} which will look up a bean from the registry and act as a cache of its metadata
*/
public class RegistryBean implements BeanHolder {
private final CamelContext context;
private final String name;
private final Registry registry;
private volatile BeanInfo beanInfo;
private volatile Class<?> clazz;
private ParameterMappingStrategy parameterMappingStrategy;
private Map<String, Object> options;
public RegistryBean(CamelContext context, String name) {
this(context.getRegistry(), context, name);
}
public RegistryBean(Registry registry, CamelContext context, String name) {
this.registry = registry;
this.context = context;
if (name != null) {
// for ref it may have "ref:" or "bean:" as prefix by mistake
if (name.startsWith("ref:")) {
this.name = name.substring(4);
} else if (name.startsWith("bean:")) {
this.name = name.substring(5);
} else {
this.name = name;
}
} else {
this.name = null;
}
}
@Override
public String toString() {
return "bean: " + name;
}
@Override
public Map<String, Object> getOptions() {
return options;
}
@Override
public void setOptions(Map<String, Object> options) {
this.options = options;
}
/**
* Creates a singleton (cached and constant) {@link org.apache.camel.component.bean.BeanHolder} from this holder.
*/
public ConstantBeanHolder createCacheHolder() {
Object bean = getBean(null);
BeanInfo info = createBeanInfo(bean);
return new ConstantBeanHolder(bean, info);
}
@Override
public Object getBean(Exchange exchange) throws NoSuchBeanException {
Object bean = doGetBean(exchange);
if (options != null && !options.isEmpty()) {
PropertyBindingSupport.build()
.withRemoveParameters(false)
.withCamelContext(getBeanInfo().getCamelContext())
.withProperties(options)
.withTarget(bean)
.bind();
}
return bean;
}
private Object doGetBean(Exchange exchange) throws NoSuchBeanException {
// must always lookup bean first
Object value = lookupBean();
if (value != null) {
// could be a class then create an instance of it
if (value instanceof Class) {
// bean is a class so create an instance of it
value = context.getInjector().newInstance((Class<?>) value);
}
return value;
}
// okay bean is not in registry, so try to resolve if its a class name and create a shared instance
if (clazz == null) {
clazz = context.getClassResolver().resolveClass(name);
}
if (clazz == null) {
// no its not a class then we cannot find the bean
throw new NoSuchBeanException(name);
}
// bean is a class so create an instance of it
return context.getInjector().newInstance(clazz);
}
@Override
public Processor getProcessor() {
return null;
}
@Override
public boolean supportProcessor() {
return false;
}
@Override
public BeanInfo getBeanInfo() {
if (beanInfo == null) {
Object bean = getBean(null);
this.beanInfo = createBeanInfo(bean);
}
return beanInfo;
}
@Override
public BeanInfo getBeanInfo(Object bean) {
return createBeanInfo(bean);
}
public String getName() {
return name;
}
public Registry getRegistry() {
return registry;
}
public CamelContext getContext() {
return context;
}
public ParameterMappingStrategy getParameterMappingStrategy() {
if (parameterMappingStrategy == null) {
parameterMappingStrategy = createParameterMappingStrategy();
}
return parameterMappingStrategy;
}
public void setParameterMappingStrategy(ParameterMappingStrategy parameterMappingStrategy) {
this.parameterMappingStrategy = parameterMappingStrategy;
}
// Implementation methods
//-------------------------------------------------------------------------
protected BeanInfo createBeanInfo(Object bean) {
return new BeanInfo(context, bean.getClass(), getParameterMappingStrategy());
}
protected ParameterMappingStrategy createParameterMappingStrategy() {
return BeanInfo.createParameterMappingStrategy(context);
}
protected Object lookupBean() {
return registry.lookupByName(name);
}
}

View File

@ -1,77 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.bean.fix;
import org.apache.camel.Exchange;
import org.apache.camel.NoSuchBeanException;
import org.apache.camel.Processor;
import java.util.Map;
/**
* Request scoped {@link org.apache.camel.component.bean.BeanHolder} wrapper.
*/
public class RequestBeanHolder implements BeanHolder {
private final BeanHolder holder;
private final String key;
public RequestBeanHolder(BeanHolder holder) {
this.holder = holder;
this.key = "CamelBeanRequestScope-" + holder.getBeanInfo().getType().getName();
}
@Override
public Map<String, Object> getOptions() {
return holder.getOptions();
}
@Override
public void setOptions(Map<String, Object> options) {
this.holder.setOptions(options);
}
@Override
public Object getBean(Exchange exchange) throws NoSuchBeanException {
Object bean = exchange.getProperty(key);
if (bean == null) {
bean = holder.getBean(exchange);
exchange.setProperty(key, bean);
}
return bean;
}
@Override
public Processor getProcessor() {
return null;
}
@Override
public boolean supportProcessor() {
return false;
}
@Override
public BeanInfo getBeanInfo() {
return holder.getBeanInfo();
}
@Override
public BeanInfo getBeanInfo(Object bean) {
return holder.getBeanInfo(bean);
}
}

View File

@ -1,76 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.beanclass.fix;
import org.apache.camel.Endpoint;
import org.apache.camel.component.bean.fix.BeanComponent;
import org.apache.camel.component.bean.fix.BeanHolder;
import org.apache.camel.component.bean.fix.ConstantBeanHolder;
import org.apache.camel.component.bean.fix.ConstantTypeBeanHolder;
import org.apache.camel.util.PropertiesHelper;
import java.util.Map;
/**
* The <a href="http://camel.apache.org/class.html">Class Component</a> is for binding JavaBeans to Camel message exchanges based on class name.
* <p/>
* This component is an extension to the {@link org.apache.camel.component.bean.BeanComponent}.
*/
@org.apache.camel.spi.annotations.Component("class")
public class ClassComponent extends BeanComponent {
public ClassComponent() {
}
@Override
protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
ClassEndpoint endpoint = new ClassEndpoint(uri, this);
endpoint.setBeanName(remaining);
// bean name is the FQN
String name = endpoint.getBeanName();
Class<?> clazz = getCamelContext().getClassResolver().resolveMandatoryClass(name);
// the bean.xxx options is for the bean
Map<String, Object> options = PropertiesHelper.extractProperties(parameters, "bean.");
endpoint.setParameters(options);
BeanHolder holder;
// if there is options then we need to create a bean instance
if (!options.isEmpty()) {
// create bean
Object bean = getCamelContext().getInjector().newInstance(clazz);
// now set additional properties on it
setProperties(bean, options);
holder = new ConstantBeanHolder(bean, getCamelContext());
} else {
// otherwise refer to the type
holder = new ConstantTypeBeanHolder(clazz, getCamelContext());
}
validateParameters(uri, options, null);
// and register the bean as a holder on the endpoint
endpoint.setBeanHolder(holder);
return endpoint;
}
}

View File

@ -1,34 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.component.beanclass.fix;
import org.apache.camel.Category;
import org.apache.camel.Component;
import org.apache.camel.component.bean.fix.BeanEndpoint;
import org.apache.camel.spi.UriEndpoint;
/**
* Invoke methods of Java beans specified by class name.
*/
@UriEndpoint(firstVersion = "2.4.0", scheme = "class", title = "Class", syntax = "class:beanName", producerOnly = true, category = {Category.CORE, Category.JAVA})
public class ClassEndpoint extends BeanEndpoint {
public ClassEndpoint(String endpointUri, Component component) {
super(endpointUri, component);
}
}

View File

@ -1,36 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.language.bean;
import org.apache.camel.component.bean.fix.BeanAnnotationExpressionFactory;
import org.apache.camel.support.language.LanguageAnnotation;
import java.lang.annotation.*;
/**
* Used to inject a bean expression into a field, property, method or parameter when using
* <a href="http://camel.apache.org/bean-integration.html">Bean Integration</a>.
*/
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@LanguageAnnotation(language = "bean", factory = BeanAnnotationExpressionFactory.class)
public @interface Bean {
String ref();
String method() default "";
}

View File

@ -1,499 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.language.bean;
import org.apache.camel.*;
import org.apache.camel.component.bean.fix.*;
import org.apache.camel.spi.Language;
import org.apache.camel.support.CamelContextHelper;
import org.apache.camel.support.ExchangeHelper;
import org.apache.camel.support.LanguageSupport;
import org.apache.camel.util.KeyValueHolder;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.OgnlHelper;
import org.apache.camel.util.StringHelper;
import java.util.List;
import java.util.Map;
import static org.apache.camel.util.ObjectHelper.hasDefaultPublicNoArgConstructor;
/**
* Evaluates an expression using a bean method invocation
*/
public class BeanExpression implements Expression, Predicate, AfterPropertiesConfigured {
private Object bean;
private String beanName;
private Class<?> type;
private String method;
private volatile BeanHolder beanHolder;
public BeanExpression(Object bean, String method) {
this.bean = bean;
this.method = method;
this.beanName = null;
this.type = null;
}
public BeanExpression(String beanName, String method) {
this.beanName = beanName;
this.method = method;
this.bean = null;
this.type = null;
}
public BeanExpression(Class<?> type, String method) {
this.type = type;
this.method = method;
this.bean = null;
this.beanName = null;
}
public Object getBean() {
return bean;
}
public void setBean(Object bean) {
this.bean = bean;
}
public String getBeanName() {
return beanName;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
public Class<?> getType() {
return type;
}
public void setType(Class<?> type) {
this.type = type;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
@Override
public void init(CamelContext context) {
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("BeanExpression[");
if (bean != null) {
sb.append(bean.toString());
} else if (beanName != null) {
sb.append(beanName);
} else if (type != null) {
sb.append(ObjectHelper.className(type));
}
if (method != null) {
sb.append(" method:").append(method);
}
sb.append("]");
return sb.toString();
}
public Object evaluate(Exchange exchange) {
if (bean == null && type == null && beanName != null && beanName.startsWith("type:")) {
// its a reference to a fqn class so load the class and use type instead
String fqn = beanName.substring(5);
try {
type = exchange.getContext().getClassResolver().resolveMandatoryClass(fqn);
beanName = null;
} catch (ClassNotFoundException e) {
throw new NoSuchBeanException(beanName, e);
}
}
// if the bean holder doesn't exist then create it using the context from the exchange
if (beanHolder == null) {
beanHolder = createBeanHolder(exchange.getContext());
}
// invoking the bean can either be the easy way or using OGNL
if (bean != null || type != null) {
validateHasMethod(exchange.getContext(), bean, type, method);
}
// validate OGNL
if (OgnlHelper.isInvalidValidOgnlExpression(method)) {
ExpressionIllegalSyntaxException cause = new ExpressionIllegalSyntaxException(method);
throw new RuntimeBeanExpressionException(exchange, beanName, method, cause);
}
if (OgnlHelper.isValidOgnlExpression(method)) {
// okay the method is an ognl expression
try {
return invokeOgnlMethod(beanHolder, beanName, method, exchange);
} catch (Exception e) {
if (e instanceof RuntimeBeanExpressionException) {
throw (RuntimeBeanExpressionException) e;
}
throw new RuntimeBeanExpressionException(exchange, getBeanName(exchange, beanName, beanHolder), method, e);
}
} else {
// regular non ognl invocation
try {
return invokeBean(beanHolder, beanName, method, exchange);
} catch (Exception e) {
if (e instanceof RuntimeBeanExpressionException) {
throw (RuntimeBeanExpressionException) e;
}
throw new RuntimeBeanExpressionException(exchange, getBeanName(exchange, beanName, beanHolder), method, e);
}
}
}
@Override
public <T> T evaluate(Exchange exchange, Class<T> type) {
Object result = evaluate(exchange);
if (Object.class == type) {
// do not use type converter if type is Object (optimize)
return (T) result;
} else {
return exchange.getContext().getTypeConverter().convertTo(type, exchange, result);
}
}
@Override
public boolean matches(Exchange exchange) {
Object value = evaluate(exchange);
return ObjectHelper.evaluateValuePredicate(value);
}
@Override
public void afterPropertiesConfigured(CamelContext camelContext) {
// lets see if we can do additional validation that the bean has valid method during creation of the expression
Object target = bean;
if (bean == null && type == null && beanName != null) {
if (beanName.startsWith("type:")) {
// its a reference to a fqn class so load the class and use type instead
String fqn = beanName.substring(5);
try {
type = camelContext.getClassResolver().resolveMandatoryClass(fqn);
beanName = null;
} catch (ClassNotFoundException e) {
throw new NoSuchBeanException(beanName, e);
}
} else {
target = CamelContextHelper.mandatoryLookup(camelContext, beanName);
}
}
validateHasMethod(camelContext, target, type, method);
// if the bean holder doesn't exist then create it
if (beanHolder == null) {
beanHolder = createBeanHolder(camelContext);
}
}
/**
* Validates the given bean has the method.
* <p/>
* This implementation will skip trying to validate OGNL method name expressions.
*
* @param context camel context
* @param bean the bean instance
* @param type the bean type
* @param method the method, can be <tt>null</tt> if no method name provided
* @throws org.apache.camel.RuntimeCamelException is thrown if bean does not have the method
*/
protected void validateHasMethod(CamelContext context, Object bean, Class<?> type, String method) {
if (method == null) {
return;
}
if (bean == null && type == null) {
throw new IllegalArgumentException("Either bean or type should be provided on " + this);
}
if (bean == null && hasDefaultPublicNoArgConstructor(type)) {
bean = context.getInjector().newInstance(type);
}
// do not try to validate ognl methods
if (OgnlHelper.isValidOgnlExpression(method)) {
return;
}
// if invalid OGNL then fail
if (OgnlHelper.isInvalidValidOgnlExpression(method)) {
ExpressionIllegalSyntaxException cause = new ExpressionIllegalSyntaxException(method);
throw RuntimeCamelException.wrapRuntimeCamelException(new MethodNotFoundException(bean != null ? bean : type, method, cause));
}
if (bean != null) {
BeanInfo info = new BeanInfo(context, bean.getClass());
if (!info.hasMethod(method)) {
throw RuntimeCamelException.wrapRuntimeCamelException(new MethodNotFoundException(null, bean, method));
}
} else {
BeanInfo info = new BeanInfo(context, type);
// must be a static method as we do not have a bean instance to invoke
if (!info.hasStaticMethod(method)) {
throw RuntimeCamelException.wrapRuntimeCamelException(new MethodNotFoundException(null, type, method, true));
}
}
}
private BeanHolder createBeanHolder(CamelContext context) {
// either use registry lookup or a constant bean
BeanHolder holder;
if (bean != null) {
holder = new ConstantBeanHolder(bean, context);
} else if (beanName != null) {
holder = new RegistryBean(context, beanName);
} else if (type != null) {
holder = new ConstantTypeBeanHolder(type, context);
} else {
throw new IllegalArgumentException("Either bean, beanName or type should be set on " + this);
}
return holder;
}
private static String getBeanName(Exchange exchange, String beanName, BeanHolder beanHolder) {
String name = beanName;
if (name == null && beanHolder != null && beanHolder.getBean(exchange) != null) {
name = beanHolder.getBean(exchange).getClass().getCanonicalName();
}
if (name == null && beanHolder != null && beanHolder.getBeanInfo() != null && beanHolder.getBeanInfo().getType() != null) {
name = beanHolder.getBeanInfo().getType().getCanonicalName();
}
return name;
}
/**
* Invokes the bean and returns the result. If an exception was thrown while invoking the bean, then the
* exception is set on the exchange.
*/
private static Object invokeBean(BeanHolder beanHolder, String beanName, String methodName, Exchange exchange) {
Object result;
BeanExpressionProcessor processor = new BeanExpressionProcessor(beanHolder);
if (methodName != null) {
processor.setMethod(methodName);
// enable OGNL like invocation
processor.setShorthandMethod(true);
}
try {
// copy the original exchange to avoid side effects on it
Exchange resultExchange = ExchangeHelper.createCopy(exchange, true);
// remove any existing exception in case we do OGNL on the exception
resultExchange.setException(null);
// force to use InOut to retrieve the result on the OUT message
resultExchange.setPattern(ExchangePattern.InOut);
processor.process(resultExchange);
// the response is always stored in OUT
result = resultExchange.hasOut() ? resultExchange.getOut().getBody() : null;
// propagate properties and headers from result
if (resultExchange.hasProperties()) {
exchange.getProperties().putAll(resultExchange.getProperties());
}
if (resultExchange.getOut().hasHeaders()) {
exchange.getIn().getHeaders().putAll(resultExchange.getOut().getHeaders());
}
// propagate exceptions
if (resultExchange.getException() != null) {
exchange.setException(resultExchange.getException());
}
} catch (Throwable e) {
throw new RuntimeBeanExpressionException(exchange, beanName, methodName, e);
}
return result;
}
/**
* To invoke a bean using a OGNL notation which denotes the chain of methods to invoke.
* <p/>
* For more advanced OGNL you may have to look for a real framework such as OGNL, Mvel or dynamic
* programming language such as Groovy.
*/
private static Object invokeOgnlMethod(BeanHolder beanHolder, String beanName, String ognl, Exchange exchange) {
// we must start with having bean as the result
Object result = beanHolder.getBean(exchange);
// copy the original exchange to avoid side effects on it
Exchange resultExchange = ExchangeHelper.createCopy(exchange, true);
// remove any existing exception in case we do OGNL on the exception
resultExchange.setException(null);
// force to use InOut to retrieve the result on the OUT message
resultExchange.setPattern(ExchangePattern.InOut);
// do not propagate any method name when using OGNL, as with OGNL we
// compute and provide the method name to explicit to invoke
resultExchange.getIn().removeHeader(Exchange.BEAN_METHOD_NAME);
// current ognl path as we go along
String ognlPath = "";
// loop and invoke each method
Object beanToCall = beanHolder.getBean(exchange);
Class<?> beanType = beanHolder.getBeanInfo().getType();
// there must be a bean to call with, we currently does not support OGNL expressions on using purely static methods
if (beanToCall == null && beanType == null) {
throw new IllegalArgumentException("Bean instance and bean type is null. OGNL bean expressions requires to have either a bean instance of the class name of the bean to use.");
}
if (ognl != null) {
// must be a valid method name according to java identifier ruling
OgnlHelper.validateMethodName(ognl);
}
// Split ognl except when this is not a Map, Array
// and we would like to keep the dots within the key name
List<String> methods = OgnlHelper.splitOgnl(ognl);
for (String methodName : methods) {
BeanHolder holder;
if (beanToCall != null) {
holder = new ConstantBeanHolder(beanToCall, exchange.getContext());
} else if (beanType != null) {
holder = new ConstantTypeBeanHolder(beanType, exchange.getContext());
} else {
holder = null;
}
// support the null safe operator
boolean nullSafe = OgnlHelper.isNullSafeOperator(methodName);
if (holder == null) {
String name = getBeanName(exchange, null, beanHolder);
throw new RuntimeBeanExpressionException(exchange, name, ognl, "last method returned null and therefore cannot continue to invoke method " + methodName + " on a null instance");
}
// keep up with how far are we doing
ognlPath += methodName;
// get rid of leading ?. or . as we only needed that to determine if null safe was enabled or not
methodName = OgnlHelper.removeLeadingOperators(methodName);
// are we doing an index lookup (eg in Map/List/array etc)?
String key = null;
KeyValueHolder<String, String> index = OgnlHelper.isOgnlIndex(methodName);
if (index != null) {
methodName = index.getKey();
key = index.getValue();
}
// only invoke if we have a method name to use to invoke
if (methodName != null) {
Object newResult = invokeBean(holder, beanName, methodName, resultExchange);
// check for exception and rethrow if we failed
if (resultExchange.getException() != null) {
throw new RuntimeBeanExpressionException(exchange, beanName, methodName, resultExchange.getException());
}
result = newResult;
}
// if there was a key then we need to lookup using the key
if (key != null) {
// if key is a nested simple expression then re-evaluate that again
if (LanguageSupport.hasSimpleFunction(key)) {
Language lan = exchange.getContext().resolveLanguage("simple");
key = lan.createExpression(key).evaluate(exchange, String.class);
}
if (key != null) {
result = lookupResult(resultExchange, key, result, nullSafe, ognlPath, holder.getBean(exchange));
}
}
// check null safe for null results
if (result == null && nullSafe) {
return null;
}
// prepare for next bean to invoke
beanToCall = result;
beanType = null;
}
return result;
}
private static Object lookupResult(Exchange exchange, String key, Object result, boolean nullSafe, String ognlPath, Object bean) {
StringHelper.notEmpty(key, "key", "in Simple language ognl path: " + ognlPath);
// trim key
key = key.trim();
// remove any enclosing quotes
key = StringHelper.removeLeadingAndEndingQuotes(key);
// try map first
Map<?, ?> map = exchange.getContext().getTypeConverter().convertTo(Map.class, result);
if (map != null) {
return map.get(key);
}
// special for list is last keyword
Integer num = exchange.getContext().getTypeConverter().tryConvertTo(Integer.class, key);
boolean checkList = key.startsWith("last") || num != null;
if (checkList) {
List<?> list = exchange.getContext().getTypeConverter().convertTo(List.class, result);
if (list != null) {
if (key.startsWith("last")) {
num = list.size() - 1;
// maybe its an expression to subtract a number after last
String after = StringHelper.after(key, "-");
if (after != null) {
Integer redux = exchange.getContext().getTypeConverter().tryConvertTo(Integer.class, after.trim());
if (redux != null) {
num -= redux;
} else {
throw new ExpressionIllegalSyntaxException(key);
}
}
}
if (num != null && num >= 0 && list.size() > num - 1 && list.size() > 0) {
return list.get(num);
}
if (!nullSafe) {
// not null safe then its mandatory so thrown out of bounds exception
throw new IndexOutOfBoundsException("Index: " + num + ", Size: " + list.size()
+ " out of bounds with List from bean: " + bean + "using OGNL path [" + ognlPath + "]");
}
}
}
if (!nullSafe) {
throw new IndexOutOfBoundsException("Key: " + key + " not found in bean: " + bean + " of type: "
+ ObjectHelper.classCanonicalName(bean) + " using OGNL path [" + ognlPath + "]");
} else {
// null safe so we can return null
return null;
}
}
}

View File

@ -1,156 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.language.bean;
import org.apache.camel.CamelContext;
import org.apache.camel.Expression;
import org.apache.camel.Predicate;
import org.apache.camel.spi.GeneratedPropertyConfigurer;
import org.apache.camel.support.ExpressionToPredicateAdapter;
import org.apache.camel.support.LanguageSupport;
import org.apache.camel.support.component.PropertyConfigurerSupport;
import org.apache.camel.util.StringHelper;
/**
* A <a href="http://camel.apache.org/bean-language.html">bean language</a>
* which uses a simple text notation to invoke methods on beans to evaluate predicates or expressions
* <p/>
* The notation is essentially <code>beanName.methodName</code> which is then invoked using the
* beanName to lookup in the <a href="http://camel.apache.org/registry.html>registry</a>
* then the method is invoked to evaluate the expression using the
* <a href="http://camel.apache.org/bean-integration.html">bean integration</a> to bind the
* {@link org.apache.camel.Exchange} to the method arguments.
* <p/>
* As of Camel 1.5 the bean language also supports invoking a provided bean by
* its classname or the bean itself.
*/
@org.apache.camel.spi.annotations.Language("bean")
public class BeanLanguage extends LanguageSupport implements GeneratedPropertyConfigurer {
private Object bean;
private Class<?> beanType;
private String ref;
private String method;
public BeanLanguage() {
}
@Override
public boolean configure(CamelContext camelContext, Object target, String name, Object value, boolean ignoreCase) {
if (target != this) {
throw new IllegalStateException("Can only configure our own instance !");
}
switch (ignoreCase ? name.toLowerCase() : name) {
case "bean":
setBean(PropertyConfigurerSupport.property(camelContext, Object.class, value));
return true;
case "beantype":
case "beanType":
setBeanType(PropertyConfigurerSupport.property(camelContext, Class.class, value));
return true;
case "ref":
setRef(PropertyConfigurerSupport.property(camelContext, String.class, value));
return true;
case "method":
setMethod(PropertyConfigurerSupport.property(camelContext, String.class, value));
return true;
default:
return false;
}
}
public Object getBean() {
return bean;
}
public void setBean(Object bean) {
this.bean = bean;
}
public Class<?> getBeanType() {
return beanType;
}
public void setBeanType(Class<?> beanType) {
this.beanType = beanType;
}
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref = ref;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
@Override
public Predicate createPredicate(String expression) {
return ExpressionToPredicateAdapter.toPredicate(createExpression(expression));
}
@Override
public Expression createExpression(String expression) {
// favour using the configured options
if (bean != null) {
return new BeanExpression(bean, method);
} else if (beanType != null) {
return new BeanExpression(beanType, method);
} else if (ref != null) {
return new BeanExpression(ref, method);
}
String beanName = expression;
String method = null;
// we support both the .method name and the ?method= syntax
// as the ?method= syntax is very common for the bean component
if (expression.contains("?method=")) {
beanName = StringHelper.before(expression, "?");
method = StringHelper.after(expression, "?method=");
} else {
//first check case :: because of my.own.Bean::method
int doubleColonIndex = expression.indexOf("::");
//need to check that not inside params
int beginOfParameterDeclaration = expression.indexOf('(');
if (doubleColonIndex > 0 && (!expression.contains("(") || doubleColonIndex < beginOfParameterDeclaration)) {
beanName = expression.substring(0, doubleColonIndex);
method = expression.substring(doubleColonIndex + 2);
} else {
int idx = expression.indexOf('.');
if (idx > 0) {
beanName = expression.substring(0, idx);
method = expression.substring(idx + 1);
}
}
}
return new BeanExpression(beanName, method);
}
@Override
public boolean isSingleton() {
return false;
}
}

View File

@ -1,57 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.language.bean;
import org.apache.camel.Exchange;
import org.apache.camel.RuntimeExpressionException;
/**
* Exception thrown if invocation of bean failed.
*/
public class RuntimeBeanExpressionException extends RuntimeExpressionException {
private static final long serialVersionUID = -7184254079414493118L;
private final Exchange exchange;
private final String beanName;
private final String method;
public RuntimeBeanExpressionException(Exchange exchange, String beanName, String method, Throwable e) {
super("Failed to invoke method: " + method + " on " + beanName + " due to: " + e, e);
this.exchange = exchange;
this.beanName = beanName;
this.method = method;
}
public RuntimeBeanExpressionException(Exchange exchange, String beanName, String method, String message) {
super("Failed to invoke method: " + method + " on " + beanName + " due " + message);
this.exchange = exchange;
this.beanName = beanName;
this.method = method;
}
public String getBeanName() {
return beanName;
}
public Exchange getExchange() {
return exchange;
}
public String getMethod() {
return method;
}
}

View File

@ -1,2 +0,0 @@
# Generated by camel build tools - do NOT edit this file!
class=org.apache.camel.component.bean.fix.BeanComponent

View File

@ -8,7 +8,7 @@
<parent>
<groupId>ru.entaxy.esb.system.core</groupId>
<artifactId>system-core</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
<relativePath>../../core/pom.xml</relativePath>
</parent>

View File

@ -8,7 +8,7 @@
<parent>
<groupId>ru.entaxy.esb.system.core</groupId>
<artifactId>system-core</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
@ -25,6 +25,10 @@
<bundle.osgi.import.pkg>
*
</bundle.osgi.import.pkg>
<!-- bundle.osgi.private.pkg>{local-packages}</bundle.osgi.private.pkg -->
<!--ru.entaxy.esb.system.core.common.error.handler.processor,
ru.entaxy.esb.system.core.common.error.handler.util-->
</properties>
<dependencies>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ru.entaxy.esb.system.core.events</groupId>
<artifactId>events</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
<relativePath>../../events/pom.xml</relativePath>
</parent>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ru.entaxy.esb.system.core.events</groupId>
<artifactId>events</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
<relativePath>../../events/pom.xml</relativePath>
</parent>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ru.entaxy.esb.system.core.events</groupId>
<artifactId>events</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
<relativePath>../../events/pom.xml</relativePath>
</parent>
@ -25,6 +25,10 @@
com.google.gson.reflect,
*
</bundle.osgi.import.pkg>
<!-- bundle.osgi.private.pkg>
ru.entaxy.esb.system.core.events.handler,
ru.entaxy.esb.system.core.events.handler.util
</bundle.osgi.private.pkg -->
<camel-eventadmin.version>3.1.0</camel-eventadmin.version>
<org.osgi.service.event.version>1.4.0</org.osgi.service.event.version>
</properties>
@ -73,13 +77,11 @@
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-gson</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<dependency>

View File

@ -34,7 +34,7 @@
<cm:property-placeholder
persistent-id="ru.entaxy.esb.system.event.handler" update-strategy="reload">
<cm:default-properties>
<cm:property name="quirtz.job.clean.cron" value="0+0/1+*+*+*+?+*"/><!-- cron - Every minite -->
<cm:property name="quirtz.job.clean.cron" value="0+0/1+*+*+*+?+*"/><!-- cron - Every minute -->
<cm:property name="mode.dev" value="false"/>
</cm:default-properties>
</cm:property-placeholder>
@ -79,6 +79,11 @@
<property name="schedulerFactory" ref="factory"/>
</bean>
<!-- NOTE: Don't delete! -->
<!-- It needs for quartz because dataSource doesn't has time to registry in jndi-->
<reference id="cache" interface="javax.sql.DataSource" filter="(osgi.jndi.service.name=entaxy.esb.cache)"
availability="mandatory"/>
<bean id="factory" class="org.quartz.impl.StdSchedulerFactory">
<argument>
<props>
@ -105,7 +110,7 @@
<route id="handlerInit" autoStartup="true">
<from uri="timer:handlerInit?repeatCount=1"/>
<to uri="bean-fix:systemSubscriptionService?method=listByDeleted(false)"/>
<to uri="bean:systemSubscriptionService?method=listByDeleted(false)"/>
<bean ref="subscriptionProcessingGenerator" method="construct(${exchange})"/>
</route>
@ -247,11 +252,11 @@
<route id="cleanProcess">
<from uri="direct-vm:cleanProcess"/>
<to uri="bean-fix:systemSubscriptionService?method=listByDeleted(true)"/>
<to uri="bean:systemSubscriptionService?method=listByDeleted(true)"/>
<to uri="direct-vm:deleteSubscriberConsumers"/>
<to uri="bean-fix:eventTopicService?method=clean"/>
<to uri="bean:eventTopicService?method=clean"/>
<log message="CleanProcess: Deleted ${body} topics" loggingLevel="TRACE"/>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ru.entaxy.esb.system.core.events</groupId>
<artifactId>events</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
<relativePath>../../events/pom.xml</relativePath>
</parent>
@ -33,13 +33,15 @@
javassist.util.proxy,
*
</bundle.osgi.import.pkg>
<!-- bundle.osgi.private.pkg>
ru.entaxy.esb.system.core.events.jpa.impl
</bundle.osgi.private.pkg -->
</properties>
<dependencies>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
<version>${osgi.version}</version>
<scope>provided</scope>
</dependency>
<dependency>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ru.entaxy.esb.system.core.events</groupId>
<artifactId>events</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
<relativePath>../../events/pom.xml</relativePath>
</parent>
@ -24,6 +24,12 @@
ru.entaxy.esb.system.core.permission.handler,
*
</bundle.osgi.import.pkg>
<!-- bundle.osgi.private.pkg>
ru.entaxy.esb.system.core.events.rest,
ru.entaxy.esb.system.core.events.rest.aggregation,
ru.entaxy.esb.system.core.events.rest.exception,
ru.entaxy.esb.system.core.events.rest.response
</bundle.osgi.private.pkg-->
</properties>

View File

@ -516,7 +516,7 @@
<log message="X-ForwardedUserId ${headers.X-ForwardedUserId}" loggingLevel="DEBUG"/>
<setProperty name="permissionCheck">
<simple>bean-fix:permissionChecker?method=check(${headers.X-ForwardedUserId}, 'account',
<simple>bean:permissionChecker?method=check(${headers.X-ForwardedUserId}, 'account',
${exchangeProperty.serviceName}, 'service', 'manage')
</simple>
</setProperty>

View File

@ -8,7 +8,7 @@
<parent>
<groupId>ru.entaxy.esb.system.core</groupId>
<artifactId>system-core</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
<relativePath>../../core/pom.xml</relativePath>
</parent>

View File

@ -8,7 +8,7 @@
<parent>
<groupId>ru.entaxy.esb.system</groupId>
<artifactId>system-parent</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
</parent>
<groupId>ru.entaxy.esb.system.core</groupId>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ru.entaxy.esb.system.core.permission</groupId>
<artifactId>permission</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
<relativePath>../../security/pom.xml</relativePath>
</parent>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ru.entaxy.esb.system.core.permission</groupId>
<artifactId>permission</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
<relativePath>../../security/pom.xml</relativePath>
</parent>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ru.entaxy.esb.system.core.permission</groupId>
<artifactId>permission</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
<relativePath>../../security/pom.xml</relativePath>
</parent>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ru.entaxy.esb.system.core.permission</groupId>
<artifactId>permission</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
<relativePath>../../security/pom.xml</relativePath>
</parent>

View File

@ -49,10 +49,10 @@
<route id="test-permission" autoStartup="{{mode.dev}}">
<from uri="timer:test-permission?period=60&amp;repeatCount=1"/>
<to uri="bean-fix:permissionService?method=add(1, 'system', '2', 'system', 'send')"/>
<to uri="bean:permissionService?method=add(1, 'system', '2', 'system', 'send')"/>
<log message="CREATE PERMISSION RECORD ${body}"/>
<to uri="bean-fix:permissionService?method=getByAllParameters(1, 'system', '2', 'system', 'send')"/>
<to uri="bean:permissionService?method=getByAllParameters(1, 'system', '2', 'system', 'send')"/>
<log message="${body}"/>
<choice>
<when>
@ -65,7 +65,7 @@
</choice>
<doTry>
<to uri="bean-fix:permissionService?method=getByAllParameters(1, '4321', '4321', '4321', '4321')"/>
<to uri="bean:permissionService?method=getByAllParameters(1, '4321', '4321', '4321', '4321')"/>
<log message="GET NOT EXISTING RECORD: TEST FAILED"/>
<doCatch>
<exception>java.lang.Exception</exception>
@ -73,7 +73,7 @@
</doCatch>
</doTry>
<to uri="bean-fix:permissionService?method=remove(1, 'system', '2', 'system', 'send')"/>
<to uri="bean:permissionService?method=remove(1, 'system', '2', 'system', 'send')"/>
<log message="DELETE PERMISSION RECORD ${body}"/>
</route>

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ru.entaxy.esb.system.core.permission</groupId>
<artifactId>permission</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
<relativePath>../../security/pom.xml</relativePath>
</parent>
@ -20,6 +20,10 @@
<bundle.osgi.export.pkg>
ru.entaxy.esb.system.core.permission.jpa.entity
</bundle.osgi.export.pkg>
<!-- bundle.osgi.private.pkg>
ru.entaxy.esb.system.core.permission.interceptor,
ru.entaxy.esb.system.core.permission.jpa.impl
</bundle.osgi.private.pkg -->
<bundle.osgi.import.pkg>
javax.xml.bind;version="[2,3)",
javax.xml.bind.annotation;version="[2,3)",
@ -38,7 +42,6 @@
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
<version>${osgi.version}</version>
<scope>provided</scope>
</dependency>
<dependency>

View File

@ -106,7 +106,7 @@ public class PermissionServiceImpl implements PermissionService {
builder.equal(root.get("objectType"), type)),
builder.and(
builder.equal(root.get("subjectId"), String.valueOf(id)),
builder.equal(root.get("objectType"), type))));
builder.equal(root.get("subjectType"), type))));
return s.createQuery(criteriaQuery).getResultList();
}

View File

@ -6,7 +6,7 @@
<parent>
<groupId>ru.entaxy.esb.system.core.permission</groupId>
<artifactId>permission</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
</parent>
<artifactId>permission-soap</artifactId>
@ -26,7 +26,6 @@
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
<version>${osgi.version}</version>
<scope>provided</scope>
</dependency>

View File

@ -77,7 +77,7 @@
<doTry>
<to uri="direct:preparePermissionCommon"/>
<to uri="bean-fix:permissionService?method=existByAllParameters(${exchangeProperty.objectId}, ${exchangeProperty.objectType},
<to uri="bean:permissionService?method=existByAllParameters(${exchangeProperty.objectId}, ${exchangeProperty.objectType},
${exchangeProperty.subjectId}, ${exchangeProperty.subjectType}, ${exchangeProperty.action})"/>
<log message="\r\nRESPONSE ${body}\r\n" loggingLevel="DEBUG"/>
@ -103,7 +103,7 @@
<xpath resultType="long">//p:permissionId</xpath>
</setProperty>
<to uri="bean-fix:permissionService?method=get(${exchangeProperty.permissionId})"/>
<to uri="bean:permissionService?method=get(${exchangeProperty.permissionId})"/>
<log message="\r\nGet permission ${body}\r\n" loggingLevel="DEBUG"/>
<to uri="direct:modelToHeaders"/>
@ -117,7 +117,7 @@
<from uri="direct:getByAllParams"/>
<to uri="direct:preparePermissionCommon"/>
<to uri="bean-fix:permissionService?method=getByAllParameters(${exchangeProperty.objectId}, ${exchangeProperty.objectType},
<to uri="bean:permissionService?method=getByAllParameters(${exchangeProperty.objectId}, ${exchangeProperty.objectType},
${exchangeProperty.subjectId}, ${exchangeProperty.subjectType}, ${exchangeProperty.action})"/>
<to uri="direct:modelToHeaders"/>
@ -130,7 +130,7 @@
<from uri="direct:create"/>
<to uri="direct:preparePermissionCommon"/>
<to uri="bean-fix:permissionService?method=add(${exchangeProperty.objectId}, ${exchangeProperty.objectType},
<to uri="bean:permissionService?method=add(${exchangeProperty.objectId}, ${exchangeProperty.objectType},
${exchangeProperty.subjectId}, ${exchangeProperty.subjectType}, ${exchangeProperty.action})"/>
<to uri="direct:modelToHeaders"/>
@ -160,7 +160,7 @@
<xpath resultType="String">//p:permission/p:action</xpath>
</setProperty>
<to uri="bean-fix:permissionService?method=update(${exchangeProperty.permissionId}, ${exchangeProperty.objectId}, ${exchangeProperty.objectType},
<to uri="bean:permissionService?method=update(${exchangeProperty.permissionId}, ${exchangeProperty.objectId}, ${exchangeProperty.objectType},
${exchangeProperty.subjectId}, ${exchangeProperty.subjectType}, ${exchangeProperty.action})"/>
<to uri="direct:modelToHeaders"/>
@ -173,7 +173,7 @@
<from uri="direct:delete"/>
<to uri="direct:preparePermissionCommon"/>
<to uri="bean-fix:permissionService?method=remove(${exchangeProperty.objectId}, ${exchangeProperty.objectType},
<to uri="bean:permissionService?method=remove(${exchangeProperty.objectId}, ${exchangeProperty.objectType},
${exchangeProperty.subjectId}, ${exchangeProperty.subjectType}, ${exchangeProperty.action})"/>
<setBody>

View File

@ -1,22 +1,24 @@
<#--
~~~~~~licensing~~~~~~
permission-soap
==========
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~~~~~~
-->
[#--
~~~~~~licensing~~~~~~
permission-soap
==========
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~~~~~~
--]
<tns:permission xmlns:tns="http://www.entaxy.ru/permission/">
<tns:permissionId>${exchange.properties.permissionId}</tns:permissionId>
<tns:objectId>${exchange.properties.objectId}</tns:objectId>

View File

@ -7,7 +7,7 @@
<parent>
<groupId>ru.entaxy.esb.system.core</groupId>
<artifactId>system-core</artifactId>
<version>1.8.0</version>
<version>1.8.1</version>
<relativePath>../../core/pom.xml</relativePath>
</parent>

View File

@ -5,7 +5,7 @@
<parent>
<artifactId>system-core</artifactId>
<groupId>ru.entaxy.esb.system.core</groupId>
<version>1.8.0</version>
<version>1.8.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -37,7 +37,6 @@
<dependency>
<groupId>org.osgi</groupId>
<artifactId>osgi.core</artifactId>
<version>${osgi.version}</version>
<scope>provided</scope>
</dependency>
<dependency>

View File

@ -1,201 +0,0 @@
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

@ -1,201 +0,0 @@
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

@ -1,12 +0,0 @@
# STORAGE :: ENTAXY :: CELLAR :: DEPLOYER
Для настройки cellar иметь установленный cellar в карафы или установить его, весь кластер должен быть объединен в группу.
Cellar ставится во все карафы кластера через feature.
Группа указывается и настраивается в конфигах org.apache.karaf.cellar.groups.cfg и org.apache.karaf.cellar.node.cfg
Также нужно в конфиг карафа ru.entaxy.esb.deployer.nexus.cfg:
cellar.group - название группы
Управление(установка, обновление, остановка, запуск) в кластере идет через команды cellar из nexus.

View File

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>deployer</artifactId>
<groupId>ru.entaxy.esb.system</groupId>
<version>1.8.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>ru.entaxy.esb.system.deployer</groupId>
<artifactId>cellar-deployer</artifactId>
<packaging>bundle</packaging>
<name>SYSTEM :: ENTAXY :: CELLAR :: DEPLOYER</name>
<description>SYSTEM :: ENTAXY :: CELLAR :: DEPLOYER</description>
<properties>
<bundle.osgi.export.pkg>
ru.entaxy.esb.system.deployer.cellar.deployer.*
</bundle.osgi.export.pkg>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.karaf.cellar</groupId>
<artifactId>org.apache.karaf.cellar.bundle</artifactId>
<version>${cellar.version}</version>
</dependency>
<dependency>
<groupId>ru.entaxy.esb.system.commons</groupId>
<artifactId>system-commons</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -1,35 +0,0 @@
/*-
* ~~~~~~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.esb.system.deployer.cellar.deployer;
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

@ -1,87 +0,0 @@
/*-
* ~~~~~~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.esb.system.deployer.cellar.deployer;
import org.apache.karaf.cellar.bundle.management.CellarBundleMBean;
import ru.entaxy.esb.system.common.exception.BundleNotFound;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.TabularData;
public class BundleControllerImpl implements BundleController {
private final CellarBundleMBean cellarBundleMBean;
private String cellarGroup = "default";
public BundleControllerImpl(CellarBundleMBean cellarBundleMBean) {
this.cellarBundleMBean = cellarBundleMBean;
}
public String installAndStartBundle(String bundleUrl, String bundleName) throws Exception {
cellarBundleMBean.install(cellarGroup, bundleUrl, true);
return getStatus(bundleName);
}
public void installBundle(String bundleUrl) throws Exception {
cellarBundleMBean.install(cellarGroup, bundleUrl);
}
public String stopBundle(String bundleName) throws Exception {
cellarBundleMBean.stop(cellarGroup, bundleName);
return getStatus(bundleName);
}
public String updateBundle(String bundleName) throws Exception {
cellarBundleMBean.update(cellarGroup, bundleName);
return getStatus(bundleName);
}
public String startBundle(String bundleName) throws Exception {
cellarBundleMBean.start(cellarGroup, bundleName);
return getStatus(bundleName);
}
public void uninstallBundle(String bundleName) throws Exception {
cellarBundleMBean.uninstall(cellarGroup, bundleName);
}
private String getStatus(String bundleName) throws Exception {
TabularData tabularData = cellarBundleMBean.getBundles(cellarGroup);
String status = null;
for (Object value : tabularData.values()) {
CompositeData compositeData = (CompositeData) value;
if (bundleName.equals(compositeData.get("name"))) {
status = compositeData.get("status").toString();
}
}
if (status == null) {
throw new BundleNotFound();
}
return status.toUpperCase();
}
public String getCellarGroup() {
return cellarGroup;
}
public void setCellarGroup(String cellarGroup) {
this.cellarGroup = cellarGroup;
}
}

View File

@ -1,45 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~~~~~~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~~~~~~
-->
<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.1.0"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
">
<cm:property-placeholder persistent-id="ru.entaxy.esb.deployer.cellar" update-strategy="reload">
<cm:default-properties>
<cm:property name="cellar.group" value="default"/>
</cm:default-properties>
</cm:property-placeholder>
<bean id="bundleController" class="ru.entaxy.esb.system.deployer.cellar.deployer.BundleControllerImpl">
<argument ref="cellarBundleMBean"/>
<property name="cellarGroup" value="${cellar.group}"/>
</bean>
<service ref="bundleController" interface="ru.entaxy.esb.system.deployer.cellar.deployer.BundleController"/>
<reference id="cellarBundleMBean"
interface="org.apache.karaf.cellar.bundle.management.CellarBundleMBean"/>
</blueprint>

View File

@ -1,201 +0,0 @@
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

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ru.entaxy.esb.system</groupId>
<artifactId>deployer</artifactId>
<version>1.8.0</version>
</parent>
<groupId>ru.entaxy.esb.system.deployer</groupId>
<artifactId>deployer-api</artifactId>
<packaging>bundle</packaging>
<name>SYSTEM :: ENTAXY :: DEPLOYER :: API</name>
<description>SYSTEM :: ENTAXY :: DEPLOYER :: API</description>
<properties>
<bundle.osgi.export.pkg>
ru.entaxy.esb.system.deployer.api.*
</bundle.osgi.export.pkg>
</properties>
</project>

View File

@ -1,28 +0,0 @@
/*-
* ~~~~~~licensing~~~~~~
* deployer-api
* ==========
* Copyright (C) 2020 - 2021 EmDev LLC
* ==========
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ~~~~~~/licensing~~~~~~
*/
package ru.entaxy.esb.system.deployer.api;
public interface BundleRepository {
String deployBlueprint(String groupId, String version, String name, String extension, byte[] data) throws Exception;
void delete(String groupId, String version, String name, String extension) throws Exception;
}

View File

@ -1,201 +0,0 @@
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

@ -1,8 +0,0 @@
# SYSTEM :: ENTAXY :: FILE SYSTEM :: DEPLOYER
Реализация интерфейса BundleRepository.
Конфигурация ru.entaxy.esb.deployer.file.system.cfg:
folder.root - корневая папка репозитория

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ru.entaxy.esb.system</groupId>
<artifactId>deployer</artifactId>
<version>1.8.0</version>
</parent>
<groupId>ru.entaxy.esb.system.deployer</groupId>
<artifactId>file-system-deployer</artifactId>
<packaging>bundle</packaging>
<name>SYSTEM :: ENTAXY :: FILE SYSTEM :: DEPLOYER</name>
<description>SYSTEM :: ENTAXY :: FILE SYSTEM :: DEPLOYER</description>
<properties>
<bundle.osgi.export.pkg>
ru.entaxy.esb.system.deployer.file.*
</bundle.osgi.export.pkg>
</properties>
<dependencies>
<dependency>
<groupId>ru.entaxy.esb.system.deployer</groupId>
<artifactId>deployer-api</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -1,64 +0,0 @@
/*-
* ~~~~~~licensing~~~~~~
* file-system-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.esb.system.deployer.file;
import ru.entaxy.esb.system.deployer.api.BundleRepository;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.regex.Matcher;
public class FileSystemRepositoryImpl implements BundleRepository {
private String folderRoot;
@Override
public String deployBlueprint(String groupId, String version, String name, String extension, byte[] data) throws Exception {
Path path = preparePath(groupId, version, name, extension);
if (!Files.exists(path.getParent())) {
Files.createDirectories(path.getParent());
}
Files.write(path, data);
return "blueprint:file:" + path.normalize();
}
@Override
public void delete(String groupId, String version, String name, String extension) throws Exception {
Files.deleteIfExists(preparePath(groupId, version, name, extension));
}
private Path preparePath(String groupId, String version, String name, String extension) {
String gpoupIdPath = groupId.replaceAll("\\.", Matcher.quoteReplacement(File.separator));
String fileName = name + "-" + version + "." + extension;
Path path = Paths.get(folderRoot, gpoupIdPath, fileName);
return path;
}
public String getFolderRoot() {
return folderRoot;
}
public void setFolderRoot(String folderRoot) {
this.folderRoot = folderRoot;
}
}

View File

@ -1,40 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~~~~~~licensing~~~~~~
file-system-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~~~~~~
-->
<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.1.0"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 https://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
">
<cm:property-placeholder persistent-id="ru.entaxy.esb.deployer.file.system" update-strategy="reload">
<cm:default-properties>
<cm:property name="folder.root" value="/opt/bundle-repository"/>
</cm:default-properties>
</cm:property-placeholder>
<bean id="bundleRepository" class="ru.entaxy.esb.system.deployer.file.FileSystemRepositoryImpl">
<property name="folderRoot" value="${folder.root}"/>
</bean>
<service interface="ru.entaxy.esb.system.deployer.api.BundleRepository" ref="bundleRepository" ranking="100"/>
</blueprint>

View File

@ -1,201 +0,0 @@
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.

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