You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2019/04/04 15:56:42 UTC
[syncope] branch master updated: [SYNCOPE-1455] Core support for
SRA gateway routes
This is an automated email from the ASF dual-hosted git repository.
ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git
The following commit(s) were added to refs/heads/master by this push:
new 891a110 [SYNCOPE-1455] Core support for SRA gateway routes
891a110 is described below
commit 891a110b9fc3e32c0362d649ad488ab47174c1c9
Author: Francesco Chicchiriccò <il...@apache.org>
AuthorDate: Thu Apr 4 17:56:30 2019 +0200
[SYNCOPE-1455] Core support for SRA gateway routes
---
.../syncope/common/lib/to/GatewayRouteTO.java | 132 +++++++++++++++++++
.../syncope/common/lib/types/AMEntitlement.java | 60 +++++++++
.../syncope/common/lib/types/FilterFactory.java | 53 ++++++++
.../syncope/common/lib/types/GatewayFilter.java | 93 +++++++++++++
.../syncope/common/lib/types/GatewayPredicate.java | 110 ++++++++++++++++
.../common/lib/types/GatewayRouteStatus.java | 30 +++++
.../syncope/common/lib/types/PredicateCond.java | 29 +++++
.../syncope/common/lib/types/PredicateFactory.java | 38 ++++++
.../rest/api/service/GatewayRouteService.java | 144 +++++++++++++++++++++
core/{persistence-api => am/logic}/pom.xml | 79 +++++------
.../syncope/core/logic/GatewayRouteLogic.java | 132 +++++++++++++++++++
.../core/logic/init/AMEntitlementLoader.java | 38 ++++++
core/am/pom.xml | 44 +++++++
core/{persistence-api => am/rest-cxf}/pom.xml | 70 +++++-----
.../rest/cxf/service/GatewayRouteServiceImpl.java | 75 +++++++++++
.../apache/syncope/core/logic/LogicContext.java | 11 +-
.../apache/syncope/core/logic/MemoryAppender.java | 3 +-
core/persistence-api/pom.xml | 5 +
.../core/persistence/api/dao/GatewayRouteDAO.java | 35 +++++
.../core/persistence/api/entity/GatewayRoute.java | 48 +++++++
.../persistence/jpa/dao/JPAGatewayRouteDAO.java | 67 ++++++++++
.../persistence/jpa/entity/JPAEntityFactory.java | 3 +
.../persistence/jpa/entity/JPAGatewayRoute.java | 116 +++++++++++++++++
.../jpa/validation/entity/GatewayRouteCheck.java | 41 ++++++
.../validation/entity/GatewayRouteValidator.java | 54 ++++++++
.../persistence/jpa/inner/GatewayRouteTest.java | 97 ++++++++++++++
.../src/test/resources/domains/MasterContent.xml | 3 +
core/pom.xml | 1 +
.../api/data/GatewayRouteDataBinder.java | 29 +++++
.../java/data/GatewayRouteDataBinderImpl.java | 50 +++++++
fit/core-reference/pom.xml | 11 ++
.../org/apache/syncope/fit/AbstractITCase.java | 4 +
.../syncope/fit/core/GatewayRouteITCase.java | 106 +++++++++++++++
sra/src/main/resources/application.properties | 9 ++
sra/src/main/resources/log4j2.xml | 21 ++-
35 files changed, 1751 insertions(+), 90 deletions(-)
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/GatewayRouteTO.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/GatewayRouteTO.java
new file mode 100644
index 0000000..f973c70
--- /dev/null
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/to/GatewayRouteTO.java
@@ -0,0 +1,132 @@
+/*
+ * 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.syncope.common.lib.to;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import javax.ws.rs.PathParam;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.syncope.common.lib.types.GatewayFilter;
+import org.apache.syncope.common.lib.types.GatewayPredicate;
+import org.apache.syncope.common.lib.types.GatewayRouteStatus;
+
+public class GatewayRouteTO implements EntityTO {
+
+ private static final long serialVersionUID = 4044528284951757870L;
+
+ private String key;
+
+ private String name;
+
+ private URI target;
+
+ private final List<GatewayFilter> filters = new ArrayList<>();
+
+ private final List<GatewayPredicate> predicates = new ArrayList<>();
+
+ private GatewayRouteStatus status;
+
+ @Override
+ public String getKey() {
+ return key;
+ }
+
+ @PathParam("key")
+ @Override
+ public void setKey(final String key) {
+ this.key = key;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public URI getTarget() {
+ return target;
+ }
+
+ public void setTarget(final URI target) {
+ this.target = target;
+ }
+
+ @XmlElementWrapper(name = "filters")
+ @XmlElement(name = "filter")
+ @JsonProperty("filters")
+ public List<GatewayFilter> getFilters() {
+ return filters;
+ }
+
+ @XmlElementWrapper(name = "predicates")
+ @XmlElement(name = "predicate")
+ @JsonProperty("predicates")
+ public List<GatewayPredicate> getPredicates() {
+ return predicates;
+ }
+
+ public GatewayRouteStatus getStatus() {
+ return status;
+ }
+
+ public void setStatus(final GatewayRouteStatus status) {
+ this.status = status;
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().
+ append(key).
+ append(name).
+ append(target).
+ append(filters).
+ append(predicates).
+ append(status).
+ build();
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final GatewayRouteTO other = (GatewayRouteTO) obj;
+ return new EqualsBuilder().
+ append(key, other.key).
+ append(name, other.name).
+ append(target, other.target).
+ append(filters, other.filters).
+ append(predicates, other.predicates).
+ append(status, other.status).
+ build();
+ }
+}
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMEntitlement.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMEntitlement.java
new file mode 100644
index 0000000..6d7d762
--- /dev/null
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/AMEntitlement.java
@@ -0,0 +1,60 @@
+/*
+ * 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.syncope.common.lib.types;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import java.util.Set;
+import java.util.TreeSet;
+
+public final class AMEntitlement {
+
+ public static final String GATEWAY_ROUTE_LIST = "GATEWAY_ROUTE_LIST";
+
+ public static final String GATEWAY_ROUTE_CREATE = "GATEWAY_ROUTE_CREATE";
+
+ public static final String GATEWAY_ROUTE_READ = "GATEWAY_ROUTE_READ";
+
+ public static final String GATEWAY_ROUTE_UPDATE = "GATEWAY_ROUTE_UPDATE";
+
+ public static final String GATEWAY_ROUTE_DELETE = "GATEWAY_ROUTE_DELETE";
+
+ public static final String GATEWAY_ROUTE_PUSH = "GATEWAY_ROUTE_PUSH";
+
+ private static final Set<String> VALUES;
+
+ static {
+ Set<String> values = new TreeSet<>();
+ for (Field field : AMEntitlement.class.getDeclaredFields()) {
+ if (Modifier.isStatic(field.getModifiers()) && String.class.equals(field.getType())) {
+ values.add(field.getName());
+ }
+ }
+ VALUES = Collections.unmodifiableSet(values);
+ }
+
+ public static Set<String> values() {
+ return VALUES;
+ }
+
+ private AMEntitlement() {
+ // private constructor for static utility class
+ }
+}
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/FilterFactory.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/FilterFactory.java
new file mode 100644
index 0000000..1120af9
--- /dev/null
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/FilterFactory.java
@@ -0,0 +1,53 @@
+/*
+ * 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.syncope.common.lib.types;
+
+import javax.xml.bind.annotation.XmlEnum;
+
+@XmlEnum
+public enum FilterFactory {
+ ADD_REQUEST_HEADER,
+ ADD_REQUEST_PARAMETER,
+ ADD_RESPONSE_HEADER,
+ HYSTRIX,
+ MODIFY_REQUEST_BODY,
+ MODIFY_RESPONSE_BODY,
+ PREFIX_PATH,
+ PRESERVE_HOST_HEADER,
+ REDIRECT,
+ REMOVE_REQUEST_HEADER,
+ REMOVE_RESPONSE_HEADER,
+ REQUEST_RATE_LIMITER,
+ REWRITE_PATH,
+ RETRY,
+ SECURE_HEADERS,
+ SET_PATH,
+ SET_REQUEST_HEADER,
+ SET_RESPONSE_HEADER,
+ REWRITE_RESPONSE_HEADER,
+ SET_STATUS,
+ SAVE_SESSION,
+ STRIP_PREFIX,
+ REQUEST_HEADER_TO_REQUEST_URI,
+ CHANGE_REQUEST_URI,
+ SET_REQIEST_SIZE,
+ FALLBACK_HEADERS,
+ CUSTOM
+
+}
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/GatewayFilter.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/GatewayFilter.java
new file mode 100644
index 0000000..cbf946e
--- /dev/null
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/GatewayFilter.java
@@ -0,0 +1,93 @@
+/*
+ * 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.syncope.common.lib.types;
+
+import java.io.Serializable;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+public class GatewayFilter implements Serializable {
+
+ private static final long serialVersionUID = -635785645207375128L;
+
+ public static class Builder {
+
+ private final GatewayFilter instance = new GatewayFilter();
+
+ public Builder factory(final FilterFactory factory) {
+ instance.setFactory(factory);
+ return this;
+ }
+
+ public Builder args(final String args) {
+ instance.setArgs(args);
+ return this;
+ }
+
+ public GatewayFilter build() {
+ return instance;
+ }
+ }
+
+ private FilterFactory factory;
+
+ private String args;
+
+ public FilterFactory getFactory() {
+ return factory;
+ }
+
+ public void setFactory(final FilterFactory factory) {
+ this.factory = factory;
+ }
+
+ public String getArgs() {
+ return args;
+ }
+
+ public void setArgs(final String args) {
+ this.args = args;
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().
+ append(factory).
+ append(args).
+ build();
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final GatewayFilter other = (GatewayFilter) obj;
+ return new EqualsBuilder().
+ append(factory, other.factory).
+ append(args, other.args).
+ build();
+ }
+}
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/GatewayPredicate.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/GatewayPredicate.java
new file mode 100644
index 0000000..27c6635
--- /dev/null
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/GatewayPredicate.java
@@ -0,0 +1,110 @@
+/*
+ * 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.syncope.common.lib.types;
+
+import java.io.Serializable;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+public class GatewayPredicate implements Serializable {
+
+ private static final long serialVersionUID = -635785645207375128L;
+
+ public static class Builder {
+
+ private final GatewayPredicate instance = new GatewayPredicate();
+
+ public Builder cond(final PredicateCond cond) {
+ instance.setCond(cond);
+ return this;
+ }
+
+ public Builder factory(final PredicateFactory factory) {
+ instance.setFactory(factory);
+ return this;
+ }
+
+ public Builder args(final String args) {
+ instance.setArgs(args);
+ return this;
+ }
+
+ public GatewayPredicate build() {
+ return instance;
+ }
+ }
+
+ private PredicateCond cond;
+
+ private PredicateFactory factory;
+
+ private String args;
+
+ public PredicateCond getCond() {
+ return cond;
+ }
+
+ public void setCond(final PredicateCond cond) {
+ this.cond = cond;
+ }
+
+ public PredicateFactory getFactory() {
+ return factory;
+ }
+
+ public void setFactory(final PredicateFactory factory) {
+ this.factory = factory;
+ }
+
+ public String getArgs() {
+ return args;
+ }
+
+ public void setArgs(final String args) {
+ this.args = args;
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().
+ append(cond).
+ append(factory).
+ append(args).
+ build();
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final GatewayPredicate other = (GatewayPredicate) obj;
+ return new EqualsBuilder().
+ append(cond, other.cond).
+ append(factory, other.factory).
+ append(args, other.args).
+ build();
+ }
+}
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/GatewayRouteStatus.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/GatewayRouteStatus.java
new file mode 100644
index 0000000..ab199e9
--- /dev/null
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/GatewayRouteStatus.java
@@ -0,0 +1,30 @@
+/*
+ * 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.syncope.common.lib.types;
+
+import javax.xml.bind.annotation.XmlEnum;
+
+@XmlEnum
+public enum GatewayRouteStatus {
+ DRAFT,
+ STAGING,
+ PUBLISHED,
+ DEPRECATED
+
+}
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/PredicateCond.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/PredicateCond.java
new file mode 100644
index 0000000..93b0bad
--- /dev/null
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/PredicateCond.java
@@ -0,0 +1,29 @@
+/*
+ * 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.syncope.common.lib.types;
+
+import javax.xml.bind.annotation.XmlEnum;
+
+@XmlEnum
+public enum PredicateCond {
+ AND,
+ OR,
+ NOT
+
+}
diff --git a/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/PredicateFactory.java b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/PredicateFactory.java
new file mode 100644
index 0000000..5cf4e77
--- /dev/null
+++ b/common/am/lib/src/main/java/org/apache/syncope/common/lib/types/PredicateFactory.java
@@ -0,0 +1,38 @@
+/*
+ * 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.syncope.common.lib.types;
+
+import javax.xml.bind.annotation.XmlEnum;
+
+@XmlEnum
+public enum PredicateFactory {
+ AFTER,
+ BEFORE,
+ BETWEEN,
+ COOKIE,
+ HEADER,
+ HOST,
+ METHOD,
+ PATH,
+ QUERY,
+ REMOTE_ADDR,
+ READ_BODY,
+ CUSTOM
+
+}
diff --git a/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GatewayRouteService.java b/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GatewayRouteService.java
new file mode 100644
index 0000000..6b957b8
--- /dev/null
+++ b/common/am/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/GatewayRouteService.java
@@ -0,0 +1,144 @@
+/*
+ * 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.syncope.common.rest.api.service;
+
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.enums.ParameterIn;
+import io.swagger.v3.oas.annotations.headers.Header;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import io.swagger.v3.oas.annotations.security.SecurityRequirement;
+import io.swagger.v3.oas.annotations.security.SecurityRequirements;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import java.util.List;
+import javax.validation.constraints.NotNull;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.to.GatewayRouteTO;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+
+/**
+ * REST operations for gateway routes.
+ */
+@Tag(name = "GatewayRoutes")
+@SecurityRequirements({
+ @SecurityRequirement(name = "BasicAuthentication"),
+ @SecurityRequirement(name = "Bearer") })
+@Path("gatewayRoutes")
+public interface GatewayRouteService extends JAXRSService {
+
+ /**
+ * Returns a list of all existing routes.
+ *
+ * @return paged list of existing routes matching the given query
+ */
+ @GET
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ List<GatewayRouteTO> list();
+
+ /**
+ * Creates a new route.
+ *
+ * @param routeTO route to be created
+ * @return Response object featuring Location header of created route
+ */
+ @ApiResponses(
+ @ApiResponse(responseCode = "201",
+ description = "Route successfully created", headers = {
+ @Header(name = RESTHeaders.RESOURCE_KEY, schema =
+ @Schema(type = "string"),
+ description = "UUID generated for the entity created"),
+ @Header(name = HttpHeaders.LOCATION, schema =
+ @Schema(type = "string"),
+ description = "URL of the entity created") }))
+ @POST
+ @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ Response create(@NotNull GatewayRouteTO routeTO);
+
+ /**
+ * Returns route with matching key.
+ *
+ * @param key key of route to be read
+ * @return route with matching key
+ */
+ @GET
+ @Path("{key}")
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ GatewayRouteTO read(@NotNull @PathParam("key") String key);
+
+ /**
+ * Updates route with matching key.
+ *
+ * @param routeTO route to be stored
+ */
+ @Parameter(name = "key", description = "Route's key", in = ParameterIn.PATH, schema =
+ @Schema(type = "string"))
+ @ApiResponses(
+ @ApiResponse(responseCode = "204", description = "Operation was successful"))
+ @PUT
+ @Path("{key}")
+ @Consumes({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ void update(@NotNull GatewayRouteTO routeTO);
+
+ /**
+ * Deletes route with matching key.
+ *
+ * @param key route key
+ */
+ @ApiResponses(
+ @ApiResponse(responseCode = "204", description = "Operation was successful"))
+ @DELETE
+ @Path("{key}")
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ void delete(@NotNull @PathParam("key") String key);
+
+ /**
+ * Push all routes to SRA.
+ */
+ @ApiResponses(
+ @ApiResponse(responseCode = "204", description = "Operation was successful"))
+ @POST
+ @Path("push")
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ void pushToSRA();
+
+ /**
+ * Push route with matching key to SRA.
+ *
+ * @param key route key
+ */
+ @ApiResponses(
+ @ApiResponse(responseCode = "204", description = "Operation was successful"))
+ @POST
+ @Path("push/{key}")
+ @Produces({ MediaType.APPLICATION_JSON, RESTHeaders.APPLICATION_YAML, MediaType.APPLICATION_XML })
+ void pushToSRA(@NotNull @PathParam("key") String key);
+}
diff --git a/core/persistence-api/pom.xml b/core/am/logic/pom.xml
similarity index 50%
copy from core/persistence-api/pom.xml
copy to core/am/logic/pom.xml
index c5a4add..600f0d7 100644
--- a/core/persistence-api/pom.xml
+++ b/core/am/logic/pom.xml
@@ -22,68 +22,57 @@ under the License.
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>org.apache.syncope</groupId>
- <artifactId>syncope-core</artifactId>
+ <groupId>org.apache.syncope.core</groupId>
+ <artifactId>syncope-core-am</artifactId>
<version>3.0.0-SNAPSHOT</version>
</parent>
- <name>Apache Syncope Core Persistence API</name>
- <description>Apache Syncope Core Persistence API</description>
- <groupId>org.apache.syncope.core</groupId>
- <artifactId>syncope-core-persistence-api</artifactId>
+ <name>Apache Syncope Core AM Logic</name>
+ <description>Apache Syncope Core AM Logic</description>
+ <groupId>org.apache.syncope.core.am</groupId>
+ <artifactId>syncope-core-am-logic</artifactId>
<packaging>jar</packaging>
<properties>
- <rootpom.basedir>${basedir}/../..</rootpom.basedir>
+ <rootpom.basedir>${basedir}/../../..</rootpom.basedir>
</properties>
<dependencies>
<dependency>
- <groupId>javax.validation</groupId>
- <artifactId>validation-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-core</artifactId>
- </dependency>
-
- <dependency>
- <groupId>net.tirasa.connid</groupId>
- <artifactId>connector-framework</artifactId>
- </dependency>
- <dependency>
- <groupId>net.tirasa.connid</groupId>
- <artifactId>connector-framework-internal</artifactId>
- </dependency>
- <dependency>
- <groupId>net.tirasa.connid</groupId>
- <artifactId>slf4j-logging</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.apache.syncope.common.idm</groupId>
- <artifactId>syncope-common-idm-lib</artifactId>
+ <groupId>org.apache.syncope.core.idrepo</groupId>
+ <artifactId>syncope-core-idrepo-logic</artifactId>
<version>${project.version}</version>
</dependency>
-
- <!-- TEST -->
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-simple</artifactId>
- <version>${slf4j.version}</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter</artifactId>
- <scope>test</scope>
- </dependency>
</dependencies>
<build>
+ <resources>
+ <resource>
+ <directory>${basedir}/src/main/resources</directory>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+
<plugins>
<plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>buildnumber-maven-plugin</artifactId>
+ <inherited>true</inherited>
+ <configuration>
+ <doCheck>false</doCheck>
+ <doUpdate>false</doUpdate>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>validate</phase>
+ <goals>
+ <goal>create</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/GatewayRouteLogic.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/GatewayRouteLogic.java
new file mode 100644
index 0000000..3d57c17
--- /dev/null
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/GatewayRouteLogic.java
@@ -0,0 +1,132 @@
+/*
+ * 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.syncope.core.logic;
+
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.syncope.common.lib.to.GatewayRouteTO;
+import org.apache.syncope.common.lib.types.AMEntitlement;
+import org.apache.syncope.core.persistence.api.dao.GatewayRouteDAO;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.entity.EntityFactory;
+import org.apache.syncope.core.persistence.api.entity.GatewayRoute;
+import org.apache.syncope.core.provisioning.api.data.GatewayRouteDataBinder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Component;
+
+@Component
+public class GatewayRouteLogic extends AbstractTransactionalLogic<GatewayRouteTO> {
+
+ @Autowired
+ private GatewayRouteDAO routeDAO;
+
+ @Autowired
+ private GatewayRouteDataBinder binder;
+
+ @Autowired
+ private EntityFactory entityFactory;
+
+ public List<GatewayRouteTO> list() {
+ return routeDAO.findAll().stream().map(binder::getGatewayRouteTO).collect(Collectors.toList());
+ }
+
+ @PreAuthorize("hasRole('" + AMEntitlement.GATEWAY_ROUTE_CREATE + "')")
+ public GatewayRouteTO create(final GatewayRouteTO routeTO) {
+ GatewayRoute route = entityFactory.newEntity(GatewayRoute.class);
+ binder.getGatewayRoute(route, routeTO);
+
+ return binder.getGatewayRouteTO(routeDAO.save(route));
+ }
+
+ @PreAuthorize("hasRole('" + AMEntitlement.GATEWAY_ROUTE_READ + "')")
+ public GatewayRouteTO read(final String key) {
+ GatewayRoute route = routeDAO.find(key);
+ if (route == null) {
+ throw new NotFoundException("GatewayRoute " + key);
+ }
+ return binder.getGatewayRouteTO(route);
+ }
+
+ @PreAuthorize("hasRole('" + AMEntitlement.GATEWAY_ROUTE_UPDATE + "')")
+ public GatewayRouteTO update(final GatewayRouteTO routeTO) {
+ GatewayRoute route = routeDAO.find(routeTO.getKey());
+ if (route == null) {
+ throw new NotFoundException("GatewayRoute " + routeTO.getKey());
+ }
+
+ binder.getGatewayRoute(route, routeTO);
+
+ return binder.getGatewayRouteTO(routeDAO.save(route));
+ }
+
+ @PreAuthorize("hasRole('" + AMEntitlement.GATEWAY_ROUTE_DELETE + "')")
+ public GatewayRouteTO delete(final String key) {
+ GatewayRoute route = routeDAO.find(key);
+ if (route == null) {
+ throw new NotFoundException("GatewayRoute " + key);
+ }
+
+ GatewayRouteTO deleted = binder.getGatewayRouteTO(route);
+ routeDAO.delete(route);
+ return deleted;
+ }
+
+ @PreAuthorize("hasRole('" + AMEntitlement.GATEWAY_ROUTE_PUSH + "')")
+ public void pushToSRA() {
+ // TODO
+ }
+
+ @PreAuthorize("hasRole('" + AMEntitlement.GATEWAY_ROUTE_PUSH + "')")
+ public void pushToSRA(final String key) {
+ // TODO
+ }
+
+ @Override
+ protected GatewayRouteTO resolveReference(final Method method, final Object... args)
+ throws UnresolvedReferenceException {
+
+ String key = null;
+
+ if (ArrayUtils.isNotEmpty(args) && ("create".equals(method.getName())
+ || "update".equals(method.getName())
+ || "delete".equals(method.getName()))) {
+ for (int i = 0; key == null && i < args.length; i++) {
+ if (args[i] instanceof String) {
+ key = (String) args[i];
+ } else if (args[i] instanceof GatewayRouteTO) {
+ key = ((GatewayRouteTO) args[i]).getKey();
+ }
+ }
+ }
+
+ if (key != null) {
+ try {
+ return binder.getGatewayRouteTO(routeDAO.find(key));
+ } catch (Throwable ignore) {
+ LOG.debug("Unresolved reference", ignore);
+ throw new UnresolvedReferenceException(ignore);
+ }
+ }
+
+ throw new UnresolvedReferenceException();
+ }
+}
diff --git a/core/am/logic/src/main/java/org/apache/syncope/core/logic/init/AMEntitlementLoader.java b/core/am/logic/src/main/java/org/apache/syncope/core/logic/init/AMEntitlementLoader.java
new file mode 100644
index 0000000..2ca422c
--- /dev/null
+++ b/core/am/logic/src/main/java/org/apache/syncope/core/logic/init/AMEntitlementLoader.java
@@ -0,0 +1,38 @@
+/*
+ * 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.syncope.core.logic.init;
+
+import org.apache.syncope.common.lib.types.EntitlementsHolder;
+import org.apache.syncope.common.lib.types.AMEntitlement;
+import org.apache.syncope.core.persistence.api.SyncopeCoreLoader;
+import org.springframework.stereotype.Component;
+
+@Component
+public class AMEntitlementLoader implements SyncopeCoreLoader {
+
+ @Override
+ public int getOrder() {
+ return 900;
+ }
+
+ @Override
+ public void load() {
+ EntitlementsHolder.getInstance().addAll(AMEntitlement.values());
+ }
+}
diff --git a/core/am/pom.xml b/core/am/pom.xml
new file mode 100644
index 0000000..c430317
--- /dev/null
+++ b/core/am/pom.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.syncope</groupId>
+ <artifactId>syncope-core</artifactId>
+ <version>3.0.0-SNAPSHOT</version>
+ </parent>
+
+ <name>Apache Syncope Core AM</name>
+ <description>Apache Syncope Core AM</description>
+ <groupId>org.apache.syncope.core</groupId>
+ <artifactId>syncope-core-am</artifactId>
+ <packaging>pom</packaging>
+
+ <properties>
+ <rootpom.basedir>${basedir}/../..</rootpom.basedir>
+ </properties>
+
+ <modules>
+ <module>logic</module>
+ <module>rest-cxf</module>
+ </modules>
+</project>
diff --git a/core/persistence-api/pom.xml b/core/am/rest-cxf/pom.xml
similarity index 54%
copy from core/persistence-api/pom.xml
copy to core/am/rest-cxf/pom.xml
index c5a4add..80de056 100644
--- a/core/persistence-api/pom.xml
+++ b/core/am/rest-cxf/pom.xml
@@ -22,71 +22,65 @@ under the License.
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>org.apache.syncope</groupId>
- <artifactId>syncope-core</artifactId>
+ <groupId>org.apache.syncope.core</groupId>
+ <artifactId>syncope-core-am</artifactId>
<version>3.0.0-SNAPSHOT</version>
</parent>
- <name>Apache Syncope Core Persistence API</name>
- <description>Apache Syncope Core Persistence API</description>
- <groupId>org.apache.syncope.core</groupId>
- <artifactId>syncope-core-persistence-api</artifactId>
+ <name>Apache Syncope Core AM REST CXF</name>
+ <description>Apache Syncope Core AM REST CXF</description>
+ <groupId>org.apache.syncope.core.am</groupId>
+ <artifactId>syncope-core-am-rest-cxf</artifactId>
<packaging>jar</packaging>
<properties>
- <rootpom.basedir>${basedir}/../..</rootpom.basedir>
+ <rootpom.basedir>${basedir}/../../..</rootpom.basedir>
</properties>
<dependencies>
- <dependency>
- <groupId>javax.validation</groupId>
- <artifactId>validation-api</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-core</artifactId>
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <scope>provided</scope>
</dependency>
<dependency>
- <groupId>net.tirasa.connid</groupId>
- <artifactId>connector-framework</artifactId>
- </dependency>
- <dependency>
- <groupId>net.tirasa.connid</groupId>
- <artifactId>connector-framework-internal</artifactId>
- </dependency>
- <dependency>
- <groupId>net.tirasa.connid</groupId>
- <artifactId>slf4j-logging</artifactId>
+ <groupId>org.apache.syncope.common.am</groupId>
+ <artifactId>syncope-common-am-rest-api</artifactId>
+ <version>${project.version}</version>
+ <classifier>javadoc</classifier>
</dependency>
-
+
<dependency>
- <groupId>org.apache.syncope.common.idm</groupId>
- <artifactId>syncope-common-idm-lib</artifactId>
+ <groupId>org.apache.syncope.core.idrepo</groupId>
+ <artifactId>syncope-core-idrepo-rest-cxf</artifactId>
<version>${project.version}</version>
</dependency>
-
- <!-- TEST -->
<dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-simple</artifactId>
- <version>${slf4j.version}</version>
- <scope>test</scope>
+ <groupId>org.apache.syncope.core.am</groupId>
+ <artifactId>syncope-core-am-logic</artifactId>
+ <version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.junit.jupiter</groupId>
- <artifactId>junit-jupiter</artifactId>
- <scope>test</scope>
+ <groupId>org.apache.syncope.common.am</groupId>
+ <artifactId>syncope-common-am-rest-api</artifactId>
+ <version>${project.version}</version>
</dependency>
</dependencies>
<build>
- <plugins>
+ <plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
</plugins>
+
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
</build>
</project>
diff --git a/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GatewayRouteServiceImpl.java b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GatewayRouteServiceImpl.java
new file mode 100644
index 0000000..f02f0c1
--- /dev/null
+++ b/core/am/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/GatewayRouteServiceImpl.java
@@ -0,0 +1,75 @@
+/*
+ * 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.syncope.core.rest.cxf.service;
+
+import java.net.URI;
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.to.GatewayRouteTO;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.GatewayRouteService;
+import org.apache.syncope.core.logic.GatewayRouteLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class GatewayRouteServiceImpl extends AbstractServiceImpl implements GatewayRouteService {
+
+ @Autowired
+ private GatewayRouteLogic logic;
+
+ @Override
+ public List<GatewayRouteTO> list() {
+ return logic.list();
+ }
+
+ @Override
+ public Response create(final GatewayRouteTO routeTO) {
+ GatewayRouteTO createdRoute = logic.create(routeTO);
+ URI location = uriInfo.getAbsolutePathBuilder().path(createdRoute.getKey()).build();
+ return Response.created(location).
+ header(RESTHeaders.RESOURCE_KEY, createdRoute.getKey()).
+ build();
+ }
+
+ @Override
+ public GatewayRouteTO read(final String key) {
+ return logic.read(key);
+ }
+
+ @Override
+ public void update(final GatewayRouteTO routeTO) {
+ logic.update(routeTO);
+ }
+
+ @Override
+ public void delete(final String key) {
+ logic.delete(key);
+ }
+
+ @Override
+ public void pushToSRA() {
+ logic.pushToSRA();
+ }
+
+ @Override
+ public void pushToSRA(final String key) {
+ logic.pushToSRA(key);
+ }
+}
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/LogicContext.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/LogicContext.java
index 475e2ef..2a6ed43 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/LogicContext.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/LogicContext.java
@@ -18,6 +18,7 @@
*/
package org.apache.syncope.core.logic;
+import java.lang.reflect.InvocationTargetException;
import org.apache.syncope.core.persistence.api.ImplementationLookup;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
@@ -53,17 +54,19 @@ public class LogicContext implements EnvironmentAware {
@Bean
public LogicInvocationHandler logicInvocationHandler()
- throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+ throws ClassNotFoundException, InstantiationException, IllegalAccessException,
+ NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
return (LogicInvocationHandler) Class.forName(env.getProperty("logicInvocationHandler")).
- newInstance();
+ getDeclaredConstructor().newInstance();
}
@Bean
public ImplementationLookup classPathScanImplementationLookup()
- throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+ throws ClassNotFoundException, InstantiationException, IllegalAccessException,
+ NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
return (ImplementationLookup) Class.forName(env.getProperty("classPathScanImplementationLookup")).
- newInstance();
+ getDeclaredConstructor().newInstance();
}
}
diff --git a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/MemoryAppender.java b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/MemoryAppender.java
index 36f6aa6..c942730 100644
--- a/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/MemoryAppender.java
+++ b/core/idrepo/logic/src/main/java/org/apache/syncope/core/logic/MemoryAppender.java
@@ -23,6 +23,7 @@ import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractAppender;
+import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
@@ -45,7 +46,7 @@ public class MemoryAppender extends AbstractAppender {
final Filter filter,
final boolean ignoreExceptions) {
- super(name, filter, null, ignoreExceptions);
+ super(name, filter, null, ignoreExceptions, Property.EMPTY_ARRAY);
this.statements = new CircularFifoQueue<>(size);
}
diff --git a/core/persistence-api/pom.xml b/core/persistence-api/pom.xml
index c5a4add..61a3643 100644
--- a/core/persistence-api/pom.xml
+++ b/core/persistence-api/pom.xml
@@ -66,6 +66,11 @@ under the License.
<artifactId>syncope-common-idm-lib</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.syncope.common.am</groupId>
+ <artifactId>syncope-common-am-lib</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<!-- TEST -->
<dependency>
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/GatewayRouteDAO.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/GatewayRouteDAO.java
new file mode 100644
index 0000000..85dbfa4
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/dao/GatewayRouteDAO.java
@@ -0,0 +1,35 @@
+/*
+ * 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.syncope.core.persistence.api.dao;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.api.entity.GatewayRoute;
+
+public interface GatewayRouteDAO extends DAO<GatewayRoute> {
+
+ GatewayRoute find(String key);
+
+ List<GatewayRoute> findAll();
+
+ GatewayRoute save(GatewayRoute route);
+
+ void delete(String key);
+
+ void delete(GatewayRoute route);
+}
diff --git a/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/GatewayRoute.java b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/GatewayRoute.java
new file mode 100644
index 0000000..70f1e6e
--- /dev/null
+++ b/core/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/GatewayRoute.java
@@ -0,0 +1,48 @@
+/*
+ * 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.syncope.core.persistence.api.entity;
+
+import java.net.URI;
+import java.util.List;
+import org.apache.syncope.common.lib.types.GatewayFilter;
+import org.apache.syncope.common.lib.types.GatewayPredicate;
+import org.apache.syncope.common.lib.types.GatewayRouteStatus;
+
+public interface GatewayRoute extends Entity {
+
+ String getName();
+
+ void setName(String name);
+
+ URI getTarget();
+
+ void setTarget(URI target);
+
+ List<GatewayFilter> getFilters();
+
+ void setFilters(List<GatewayFilter> filters);
+
+ List<GatewayPredicate> getPredicates();
+
+ void setPredicates(List<GatewayPredicate> predicates);
+
+ GatewayRouteStatus getStatus();
+
+ void setStatus(GatewayRouteStatus status);
+}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGatewayRouteDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGatewayRouteDAO.java
new file mode 100644
index 0000000..4466ca9
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAGatewayRouteDAO.java
@@ -0,0 +1,67 @@
+/*
+ * 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.syncope.core.persistence.jpa.dao;
+
+import java.util.List;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.core.persistence.api.dao.GatewayRouteDAO;
+import org.apache.syncope.core.persistence.api.entity.GatewayRoute;
+import org.apache.syncope.core.persistence.jpa.entity.JPAGatewayRoute;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+@Repository
+public class JPAGatewayRouteDAO extends AbstractDAO<GatewayRoute> implements GatewayRouteDAO {
+
+ @Transactional(readOnly = true)
+ @Override
+ public GatewayRoute find(final String key) {
+ return entityManager().find(JPAGatewayRoute.class, key);
+ }
+
+ @Transactional(readOnly = true)
+ @Override
+ public List<GatewayRoute> findAll() {
+ TypedQuery<GatewayRoute> query = entityManager().createQuery(
+ "SELECT e FROM " + JPAGatewayRoute.class.getSimpleName() + " e", GatewayRoute.class);
+
+ return query.getResultList();
+ }
+
+ @Override
+ @Transactional(rollbackFor = Throwable.class)
+ public GatewayRoute save(final GatewayRoute report) {
+ return entityManager().merge(report);
+ }
+
+ @Override
+ public void delete(final String key) {
+ GatewayRoute report = find(key);
+ if (report == null) {
+ return;
+ }
+
+ delete(report);
+ }
+
+ @Override
+ public void delete(final GatewayRoute report) {
+ entityManager().remove(report);
+ }
+}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
index 81be309..9d46c27 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAEntityFactory.java
@@ -130,6 +130,7 @@ import org.apache.syncope.core.persistence.api.entity.resource.OrgUnit;
import org.apache.syncope.core.persistence.jpa.entity.resource.JPAOrgUnit;
import org.apache.syncope.core.persistence.api.entity.DynRealm;
import org.apache.syncope.core.persistence.api.entity.DynRealmMembership;
+import org.apache.syncope.core.persistence.api.entity.GatewayRoute;
import org.apache.syncope.core.persistence.api.entity.Implementation;
import org.apache.syncope.core.persistence.api.entity.Privilege;
import org.apache.syncope.core.persistence.api.entity.Remediation;
@@ -300,6 +301,8 @@ public class JPAEntityFactory implements EntityFactory {
result = (E) new JPARemediation();
} else if (reference.equals(Batch.class)) {
result = (E) new JPABatch();
+ } else if (reference.equals(GatewayRoute.class)) {
+ result = (E) new JPAGatewayRoute();
} else {
throw new IllegalArgumentException("Could not find a JPA implementation of " + reference.getName());
}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAGatewayRoute.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAGatewayRoute.java
new file mode 100644
index 0000000..8aee362
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAGatewayRoute.java
@@ -0,0 +1,116 @@
+/*
+ * 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.syncope.core.persistence.jpa.entity;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.Lob;
+import javax.persistence.Table;
+import javax.validation.constraints.NotNull;
+import org.apache.syncope.common.lib.types.GatewayFilter;
+import org.apache.syncope.common.lib.types.GatewayPredicate;
+import org.apache.syncope.common.lib.types.GatewayRouteStatus;
+import org.apache.syncope.core.persistence.api.entity.GatewayRoute;
+import org.apache.syncope.core.persistence.jpa.validation.entity.GatewayRouteCheck;
+import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+
+@Entity
+@Table(name = JPAGatewayRoute.TABLE)
+@GatewayRouteCheck
+public class JPAGatewayRoute extends AbstractGeneratedKeyEntity implements GatewayRoute {
+
+ private static final long serialVersionUID = -8718852361106840530L;
+
+ public static final String TABLE = "GatewayRoute";
+
+ @Column(unique = true, nullable = false)
+ private String name;
+
+ private String target;
+
+ @Lob
+ private String predicates;
+
+ @Lob
+ private String filters;
+
+ @NotNull
+ @Enumerated(EnumType.STRING)
+ private GatewayRouteStatus status;
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ @Override
+ public URI getTarget() {
+ return URI.create(target);
+ }
+
+ @Override
+ public void setTarget(final URI target) {
+ this.target = target == null ? null : target.toASCIIString();
+ }
+
+ @Override
+ public List<GatewayFilter> getFilters() {
+ return filters == null
+ ? Collections.emptyList()
+ : Arrays.asList(POJOHelper.deserialize(filters, GatewayFilter[].class));
+ }
+
+ @Override
+ public void setFilters(final List<GatewayFilter> filters) {
+ this.filters = POJOHelper.serialize(filters);
+ }
+
+ @Override
+ public List<GatewayPredicate> getPredicates() {
+ return predicates == null
+ ? Collections.emptyList()
+ : Arrays.asList(POJOHelper.deserialize(predicates, GatewayPredicate[].class));
+ }
+
+ @Override
+ public void setPredicates(final List<GatewayPredicate> predicates) {
+ this.predicates = POJOHelper.serialize(predicates);
+ }
+
+ @Override
+ public GatewayRouteStatus getStatus() {
+ return status;
+ }
+
+ @Override
+ public void setStatus(final GatewayRouteStatus status) {
+ this.status = status;
+ }
+}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/GatewayRouteCheck.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/GatewayRouteCheck.java
new file mode 100644
index 0000000..1735d2d
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/GatewayRouteCheck.java
@@ -0,0 +1,41 @@
+/*
+ * 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.syncope.core.persistence.jpa.validation.entity;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = GatewayRouteValidator.class)
+@Documented
+public @interface GatewayRouteCheck {
+
+ String message() default "{org.apache.syncope.core.persistence.validation.gatewayroute}";
+
+ Class<?>[] groups() default {};
+
+ Class<? extends Payload>[] payload() default {};
+}
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/GatewayRouteValidator.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/GatewayRouteValidator.java
new file mode 100644
index 0000000..490528f
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/GatewayRouteValidator.java
@@ -0,0 +1,54 @@
+/*
+ * 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.syncope.core.persistence.jpa.validation.entity;
+
+import javax.validation.ConstraintValidatorContext;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.core.persistence.api.entity.GatewayRoute;
+
+public class GatewayRouteValidator extends AbstractValidator<GatewayRouteCheck, GatewayRoute> {
+
+ @Override
+ public boolean isValid(final GatewayRoute route, final ConstraintValidatorContext context) {
+ context.disableDefaultConstraintViolation();
+
+ boolean isValid = true;
+
+ if (isHtml(route.getName())) {
+ context.buildConstraintViolationWithTemplate(
+ getTemplate(EntityViolationType.InvalidName, "Invalid name")).
+ addPropertyNode("name").addConstraintViolation();
+
+ isValid = false;
+ }
+
+ if (route.getPredicates().size() > 1) {
+ if (route.getPredicates().stream().allMatch(predicate -> predicate.getCond() != null)) {
+ context.buildConstraintViolationWithTemplate(
+ getTemplate(EntityViolationType.InvalidValueList,
+ "Cond must be set when predicates are more than one")).
+ addPropertyNode("predicates").addConstraintViolation();
+ }
+
+ isValid = false;
+ }
+
+ return isValid;
+ }
+}
diff --git a/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/GatewayRouteTest.java b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/GatewayRouteTest.java
new file mode 100644
index 0000000..2bcc959
--- /dev/null
+++ b/core/persistence-jpa/src/test/java/org/apache/syncope/core/persistence/jpa/inner/GatewayRouteTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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.syncope.core.persistence.jpa.inner;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+import javax.ws.rs.HttpMethod;
+import org.apache.syncope.common.lib.types.FilterFactory;
+import org.apache.syncope.common.lib.types.GatewayFilter;
+import org.apache.syncope.common.lib.types.GatewayPredicate;
+import org.apache.syncope.common.lib.types.GatewayRouteStatus;
+import org.apache.syncope.common.lib.types.PredicateFactory;
+import org.apache.syncope.core.persistence.api.dao.GatewayRouteDAO;
+import org.apache.syncope.core.persistence.api.entity.GatewayRoute;
+import org.apache.syncope.core.persistence.jpa.AbstractTest;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional("Master")
+public class GatewayRouteTest extends AbstractTest {
+
+ @Autowired
+ private GatewayRouteDAO routeDAO;
+
+ @Test
+ public void find() {
+ GatewayRoute route = routeDAO.find("ec7bada2-3dd6-460c-8441-65521d005ffa");
+ assertNotNull(route);
+ assertEquals(GatewayRouteStatus.PUBLISHED, route.getStatus());
+ assertEquals(1, route.getPredicates().size());
+
+ route = routeDAO.find(UUID.randomUUID().toString());
+ assertNull(route);
+ }
+
+ @Test
+ public void findAll() {
+ List<GatewayRoute> routes = routeDAO.findAll();
+ assertNotNull(routes);
+ assertEquals(1, routes.size());
+ }
+
+ @Test
+ public void save() {
+ GatewayRoute route = entityFactory.newEntity(GatewayRoute.class);
+ route.setName("just for test");
+ route.setTarget(URI.create("http://httpbin.org:80"));
+ route.setPredicates(Arrays.asList(new GatewayPredicate.Builder().
+ factory(PredicateFactory.METHOD).args(HttpMethod.GET).build()));
+ route.setFilters(Arrays.asList(new GatewayFilter.Builder().
+ factory(FilterFactory.ADD_REQUEST_HEADER).args("X-Request-Foo, Bar").build()));
+ route.setStatus(GatewayRouteStatus.DRAFT);
+
+ int beforeCount = routeDAO.findAll().size();
+
+ route = routeDAO.save(route);
+ assertNotNull(route);
+ assertNotNull(route.getKey());
+
+ int afterCount = routeDAO.findAll().size();
+ assertEquals(afterCount, beforeCount + 1);
+ }
+
+ @Test
+ public void delete() {
+ GatewayRoute route = routeDAO.find("ec7bada2-3dd6-460c-8441-65521d005ffa");
+ assertNotNull(route);
+
+ routeDAO.delete("ec7bada2-3dd6-460c-8441-65521d005ffa");
+
+ route = routeDAO.find("ec7bada2-3dd6-460c-8441-65521d005ffa");
+ assertNull(route);
+ }
+}
diff --git a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
index fe0077d..4bf6a5e 100644
--- a/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
+++ b/core/persistence-jpa/src/test/resources/domains/MasterContent.xml
@@ -2558,4 +2558,7 @@ $$ }
<SyncopeLogger logName="syncope.audit.[LOGIC]:[SyncopeLogic]:[]:[isSelfRegAllowed]:[SUCCESS]" logLevel="DEBUG" logType="AUDIT"/>
<SecurityQuestion id="887028ea-66fc-41e7-b397-620d7ea6dfbb" content="What's your mother's maiden name?"/>
+
+ <GatewayRoute id="ec7bada2-3dd6-460c-8441-65521d005ffa" name="basic1" target="http://httpbin.org:80" status="PUBLISHED"
+ predicates="[{"cond":null,"factory":"METHOD","args":"GET"}]"/>
</dataset>
diff --git a/core/pom.xml b/core/pom.xml
index aed7643..27d3585 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -79,6 +79,7 @@ under the License.
<modules>
<module>idrepo</module>
<module>idm</module>
+ <module>am</module>
<module>persistence-api</module>
<module>persistence-jpa</module>
<module>persistence-jpa-json</module>
diff --git a/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/GatewayRouteDataBinder.java b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/GatewayRouteDataBinder.java
new file mode 100644
index 0000000..d879f71
--- /dev/null
+++ b/core/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/data/GatewayRouteDataBinder.java
@@ -0,0 +1,29 @@
+/*
+ * 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.syncope.core.provisioning.api.data;
+
+import org.apache.syncope.common.lib.to.GatewayRouteTO;
+import org.apache.syncope.core.persistence.api.entity.GatewayRoute;
+
+public interface GatewayRouteDataBinder {
+
+ void getGatewayRoute(GatewayRoute report, GatewayRouteTO reportTO);
+
+ GatewayRouteTO getGatewayRouteTO(GatewayRoute report);
+}
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GatewayRouteDataBinderImpl.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GatewayRouteDataBinderImpl.java
new file mode 100644
index 0000000..ac7e563
--- /dev/null
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/GatewayRouteDataBinderImpl.java
@@ -0,0 +1,50 @@
+/*
+ * 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.syncope.core.provisioning.java.data;
+
+import org.apache.syncope.common.lib.to.GatewayRouteTO;
+import org.apache.syncope.core.persistence.api.entity.GatewayRoute;
+import org.apache.syncope.core.provisioning.api.data.GatewayRouteDataBinder;
+import org.springframework.stereotype.Component;
+
+@Component
+public class GatewayRouteDataBinderImpl implements GatewayRouteDataBinder {
+
+ @Override
+ public void getGatewayRoute(final GatewayRoute route, final GatewayRouteTO routeTO) {
+ route.setName(routeTO.getName());
+ route.setTarget(routeTO.getTarget());
+ route.setFilters(routeTO.getFilters());
+ route.setPredicates(routeTO.getPredicates());
+ route.setStatus(routeTO.getStatus());
+ }
+
+ @Override
+ public GatewayRouteTO getGatewayRouteTO(final GatewayRoute route) {
+ GatewayRouteTO routeTO = new GatewayRouteTO();
+ routeTO.setKey(route.getKey());
+ routeTO.setName(route.getName());
+ routeTO.setTarget(route.getTarget());
+ routeTO.getFilters().addAll(route.getFilters());
+ routeTO.getPredicates().addAll(route.getPredicates());
+ routeTO.setStatus(route.getStatus());
+
+ return routeTO;
+ }
+}
diff --git a/fit/core-reference/pom.xml b/fit/core-reference/pom.xml
index 5a156c9..422ed24 100644
--- a/fit/core-reference/pom.xml
+++ b/fit/core-reference/pom.xml
@@ -51,6 +51,11 @@ under the License.
<artifactId>syncope-core-idm-rest-cxf</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.syncope.core.am</groupId>
+ <artifactId>syncope-core-am-rest-cxf</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<!-- TEST -->
<dependency>
@@ -72,6 +77,12 @@ under the License.
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.apache.syncope.client.am</groupId>
+ <artifactId>syncope-client-am-lib</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
<groupId>org.apache.syncope.client.idm</groupId>
<artifactId>syncope-client-idm-console</artifactId>
<version>${project.version}</version>
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
index 1e75b55..adcb34e 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java
@@ -119,6 +119,7 @@ import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.apache.syncope.common.rest.api.service.UserRequestService;
import org.apache.syncope.common.rest.api.service.BpmnProcessService;
+import org.apache.syncope.common.rest.api.service.GatewayRouteService;
import org.apache.syncope.common.rest.api.service.UserWorkflowTaskService;
public abstract class AbstractITCase {
@@ -265,6 +266,8 @@ public abstract class AbstractITCase {
protected static RemediationService remediationService;
+ protected static GatewayRouteService gatewayRouteService;
+
protected static CamelRouteService camelRouteService;
protected static SAML2SPService saml2SpService;
@@ -343,6 +346,7 @@ public abstract class AbstractITCase {
securityQuestionService = adminClient.getService(SecurityQuestionService.class);
implementationService = adminClient.getService(ImplementationService.class);
remediationService = adminClient.getService(RemediationService.class);
+ gatewayRouteService = adminClient.getService(GatewayRouteService.class);
camelRouteService = adminClient.getService(CamelRouteService.class);
saml2SpService = adminClient.getService(SAML2SPService.class);
saml2IdPService = adminClient.getService(SAML2IdPService.class);
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GatewayRouteITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GatewayRouteITCase.java
new file mode 100644
index 0000000..5d4f8c4
--- /dev/null
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/GatewayRouteITCase.java
@@ -0,0 +1,106 @@
+/*
+ * 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.syncope.fit.core;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.net.URI;
+import java.util.List;
+import java.util.UUID;
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.GatewayRouteTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.FilterFactory;
+import org.apache.syncope.common.lib.types.GatewayFilter;
+import org.apache.syncope.common.lib.types.GatewayPredicate;
+import org.apache.syncope.common.lib.types.GatewayRouteStatus;
+import org.apache.syncope.common.lib.types.PredicateFactory;
+import org.apache.syncope.common.rest.api.service.GatewayRouteService;
+import org.apache.syncope.fit.AbstractITCase;
+import org.junit.jupiter.api.Test;
+
+public class GatewayRouteITCase extends AbstractITCase {
+
+ @Test
+ public void read() {
+ GatewayRouteTO route = gatewayRouteService.read("ec7bada2-3dd6-460c-8441-65521d005ffa");
+ assertNotNull(route);
+ assertEquals(GatewayRouteStatus.PUBLISHED, route.getStatus());
+ assertEquals(1, route.getPredicates().size());
+
+ try {
+ gatewayRouteService.read(UUID.randomUUID().toString());
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.NotFound, e.getType());
+ }
+ }
+
+ @Test
+ public void findAll() {
+ List<GatewayRouteTO> routes = gatewayRouteService.list();
+ assertNotNull(routes);
+ assertFalse(routes.isEmpty());
+ }
+
+ @Test
+ public void createUpdateDelete() {
+ GatewayRouteTO route = new GatewayRouteTO();
+ route.setName("just for test");
+ route.setTarget(URI.create("http://httpbin.org:80"));
+ route.getPredicates().add(new GatewayPredicate.Builder().
+ factory(PredicateFactory.METHOD).args(HttpMethod.GET).build());
+ route.getFilters().add(new GatewayFilter.Builder().
+ factory(FilterFactory.ADD_REQUEST_HEADER).args("X-Request-Foo, Bar").build());
+ route.setStatus(GatewayRouteStatus.DRAFT);
+
+ int beforeCount = gatewayRouteService.list().size();
+
+ Response response = gatewayRouteService.create(route);
+ assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+ route = getObject(response.getLocation(), GatewayRouteService.class, GatewayRouteTO.class);
+ assertNotNull(route);
+ assertNotNull(route.getKey());
+
+ int afterCount = gatewayRouteService.list().size();
+ assertEquals(afterCount, beforeCount + 1);
+
+ route.setStatus(GatewayRouteStatus.STAGING);
+ gatewayRouteService.update(route);
+ route = gatewayRouteService.read(route.getKey());
+ assertEquals(GatewayRouteStatus.STAGING, route.getStatus());
+
+ gatewayRouteService.delete(route.getKey());
+
+ try {
+ gatewayRouteService.read(route.getKey());
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.NotFound, e.getType());
+ }
+
+ int endCount = gatewayRouteService.list().size();
+ assertEquals(endCount, beforeCount);
+ }
+}
diff --git a/sra/src/main/resources/application.properties b/sra/src/main/resources/application.properties
index 5a56388..cc8c14b 100644
--- a/sra/src/main/resources/application.properties
+++ b/sra/src/main/resources/application.properties
@@ -19,3 +19,12 @@ spring.groovy.template.check-template-location=false
spring.main.banner-mode=log
server.port=8080
+
+management.endpoint.gateway.enabled=true
+management.endpoints.web.exposure.include=gateway
+
+spring.cloud.gateway.metrics.enabled=true
+management.endpoint.metrics.enabled=true
+management.endpoints.web.exposure.include=*
+management.endpoint.prometheus.enabled=true
+management.metrics.export.prometheus.enabled=true
diff --git a/sra/src/main/resources/log4j2.xml b/sra/src/main/resources/log4j2.xml
index 59d9264..d7211f5 100644
--- a/sra/src/main/resources/log4j2.xml
+++ b/sra/src/main/resources/log4j2.xml
@@ -22,7 +22,7 @@ under the License.
<appenders>
<RollingRandomAccessFile name="main" fileName="${log.directory}/sra.log"
- filePattern="${log.directory}/console-%d{yyyy-MM-dd}.log.gz"
+ filePattern="${log.directory}/sra-%d{yyyy-MM-dd}.log.gz"
immediateFlush="false" append="true">
<PatternLayout>
<pattern>%d{HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
@@ -33,6 +33,18 @@ under the License.
</Policies>
</RollingRandomAccessFile>
+ <RollingRandomAccessFile name="access" fileName="${log.directory}/sra-access.log"
+ filePattern="${log.directory}/sra-access-%d{yyyy-MM-dd}.log.gz"
+ immediateFlush="false" append="true">
+ <PatternLayout>
+ <pattern>%d{HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
+ </PatternLayout>
+ <Policies>
+ <TimeBasedTriggeringPolicy/>
+ <SizeBasedTriggeringPolicy size="250 MB"/>
+ </Policies>
+ </RollingRandomAccessFile>
+
</appenders>
<loggers>
@@ -44,7 +56,12 @@ under the License.
<asyncLogger name="org.apache.syncope.sra" additivity="false" level="INFO">
<appender-ref ref="main"/>
</asyncLogger>
-
+
+ <!-- Requires -Dreactor.netty.http.server.accessLogEnabled=true to work-->
+ <asyncLogger name="reactor.netty.http.server.AccessLog" additivity="false" level="INFO">
+ <appender-ref ref="access"/>
+ </asyncLogger>
+
<root level="INFO">
<appender-ref ref="main"/>
</root>