[java-sp-server] branch main updated: Start fleshing out Application layer.
Scott Cantor
cantor.2 at osu.edu
Fri Jun 3 13:12:31 UTC 2022
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository java-sp-server.
View the commit online:
http://git.shibboleth.net/view/?p=java-sp-server.git;a=commit;h=4d3963cf3f87c178363ce3aaf3694bba917a2476
The following commit(s) were added to refs/heads/main by this push:
new 4d3963c Start fleshing out Application layer.
4d3963c is described below
commit 4d3963cf3f87c178363ce3aaf3694bba917a2476
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Fri Jun 3 09:12:25 2022 -0400
Start fleshing out Application layer.
---
sp-conf-impl/.classpath | 6 +-
.../net/shibboleth/sp/conf/endpoints-system.xml | 10 ++-
.../net/shibboleth/sp/remoting/impl/echo.msg | 2 +-
.../sp/remoting/impl/test.application.msg | 3 +
sp-conf/src/main/resources/conf/applications.xml | 19 +++++
.../main/java/net/shibboleth/sp/Application.java | 42 ++++++++++
.../main/java/net/shibboleth/sp/package-info.java | 19 +++++
.../shibboleth/sp/remoting/AbstractEndpoint.java | 6 +-
...tractEndpoint.java => ApplicationEndpoint.java} | 37 +++++----
...anager.java => ApplicationEndpointManager.java} | 18 ++---
.../shibboleth/sp/remoting/EndpointManager.java | 2 +-
.../net/shibboleth/sp/impl/BasicApplication.java | 92 ++++++++++++++++++++++
.../impl/BasicApplicationEndpointManager.java | 69 ++++++++++++++++
13 files changed, 287 insertions(+), 38 deletions(-)
diff --git a/sp-conf-impl/.classpath b/sp-conf-impl/.classpath
index 64dc7ce..5542cbf 100644
--- a/sp-conf-impl/.classpath
+++ b/sp-conf-impl/.classpath
@@ -6,11 +6,7 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
- <classpathentry excluding="**" kind="src" path="src/main/resources">
- <attributes>
- <attribute name="maven.pomderived" value="true"/>
- </attributes>
- </classpathentry>
+ <classpathentry kind="src" path="src/main/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes>
<attribute name="module" value="true"/>
diff --git a/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/endpoints-system.xml b/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/endpoints-system.xml
index db2623c..10cb8ce 100644
--- a/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/endpoints-system.xml
+++ b/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/endpoints-system.xml
@@ -12,7 +12,7 @@
default-init-method="initialize"
default-destroy-method="destroy">
- <!-- Needed to allow for auto-wiring of componnents. -->
+ <!-- Needed to allow for auto-wiring of components. -->
<context:annotation-config />
<!-- ServiceableComponent exposed to the root context. -->
@@ -23,6 +23,9 @@
<!-- This bean auto-wires the remoting endpoints into a map exposed by the surrounding service. -->
<bean id="shibboleth.EndpointManager" class="net.shibboleth.sp.remoting.impl.BasicEndpointManager" />
+ <!-- This bean auto-wires the application-aware endpoints into a map. -->
+ <bean id="shibboleth.ApplicationEndpointManager" class="net.shibboleth.sp.remoting.impl.BasicApplicationEndpointManager" />
+
<!-- Auto-wired remoting endpoints. -->
<bean class="net.shibboleth.sp.remoting.endpoint.impl.Echo" />
@@ -30,6 +33,11 @@
<bean class="net.shibboleth.sp.remoting.endpoint.impl.XMLParser"
p:parserPool-ref="shibboleth.DefaultParserPool" />
+ <bean id="shibboleth.Application" class="net.shibboleth.sp.impl.BasicApplication" abstract="true"
+ p:endpointManager-ref="shibboleth.ApplicationEndpointManager" />
+
+ <import resource="${sp.home}/conf/applications.xml" />
+
<!-- Wildcard import hook for plugins. -->
<import resource="classpath*:/META-INF/net/shibboleth/sp/service/provider/postconfig.xml" />
diff --git a/sp-conf-impl/src/test/resources/net/shibboleth/sp/remoting/impl/echo.msg b/sp-conf-impl/src/test/resources/net/shibboleth/sp/remoting/impl/echo.msg
index c14dd5c..698334b 100644
--- a/sp-conf-impl/src/test/resources/net/shibboleth/sp/remoting/impl/echo.msg
+++ b/sp-conf-impl/src/test/resources/net/shibboleth/sp/remoting/impl/echo.msg
@@ -1,2 +1,2 @@
-echo 1 abc123
+net.shibboleth.sp.Echo 1 abc123
diff --git a/sp-conf-impl/src/test/resources/net/shibboleth/sp/remoting/impl/test.application.msg b/sp-conf-impl/src/test/resources/net/shibboleth/sp/remoting/impl/test.application.msg
new file mode 100644
index 0000000..9e0eb7b
--- /dev/null
+++ b/sp-conf-impl/src/test/resources/net/shibboleth/sp/remoting/impl/test.application.msg
@@ -0,0 +1,3 @@
+sp.example.org-default 4 1
+op 1 foo
+
diff --git a/sp-conf/src/main/resources/conf/applications.xml b/sp-conf/src/main/resources/conf/applications.xml
new file mode 100644
index 0000000..663b35b
--- /dev/null
+++ b/sp-conf/src/main/resources/conf/applications.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:util="http://www.springframework.org/schema/util"
+ xmlns:p="http://www.springframework.org/schema/p"
+ xmlns:c="http://www.springframework.org/schema/c"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
+ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
+
+ default-init-method="initialize"
+ default-destroy-method="destroy">
+
+ <!-- This is the master file defining the Applications to deploy on behalf of agents. -->
+
+ <bean id="sp.example.org-default" parent="shibboleth.Application" />
+
+</beans>
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/Application.java b/sp-server-api/src/main/java/net/shibboleth/sp/Application.java
new file mode 100644
index 0000000..a24b3cc
--- /dev/null
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/Application.java
@@ -0,0 +1,42 @@
+/*
+ * 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
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 net.shibboleth.sp;
+
+import javax.annotation.Nonnull;
+import javax.annotation.concurrent.ThreadSafe;
+
+import net.shibboleth.sp.remoting.Endpoint;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.component.IdentifiedComponent;
+
+/**
+ * A collection of resources protected by the SP and treated as a unit for the purposes of
+ * the configuration.
+ *
+ * <p>Most protocol-specific settings and services are associated with an instance of this
+ * interface either through instantiation or method inputs.</p>
+ *
+ * <p>Applications are an endpoint for messages from agents and are expected to handle a
+ * large range of messages by dispatching them internally to other components.</p>
+ */
+ at ThreadSafe
+public interface Application extends IdentifiedComponent, Endpoint {
+
+ /** Name of common "operation" member to signal receiving component. */
+ @Nonnull @NotEmpty static String OPERATION = "op";
+
+ // TODO: Expose various injected services for use by ApplicationEndpoints.
+}
\ No newline at end of file
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/package-info.java b/sp-server-api/src/main/java/net/shibboleth/sp/package-info.java
new file mode 100644
index 0000000..dd814b6
--- /dev/null
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * 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
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Core APIs for the SP.
+ */
+
+package net.shibboleth.sp;
\ No newline at end of file
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/remoting/AbstractEndpoint.java b/sp-server-api/src/main/java/net/shibboleth/sp/remoting/AbstractEndpoint.java
index 2dbe6ef..25443a3 100644
--- a/sp-server-api/src/main/java/net/shibboleth/sp/remoting/AbstractEndpoint.java
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/remoting/AbstractEndpoint.java
@@ -17,7 +17,7 @@ package net.shibboleth.sp.remoting;
import javax.annotation.Nonnull;
-import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
+import net.shibboleth.utilities.java.support.component.AbstractIdentifiableInitializableComponent;
import net.shibboleth.utilities.java.support.component.ComponentSupport;
import net.shibboleth.utilities.java.support.ddf.DDF;
import net.shibboleth.utilities.java.support.logic.Constraint;
@@ -25,8 +25,8 @@ import net.shibboleth.utilities.java.support.logic.Constraint;
/**
* Simple {@link Endpoint} implementation.
*/
-public abstract class AbstractEndpoint extends AbstractInitializableComponent implements Endpoint {
-
+public abstract class AbstractEndpoint extends AbstractIdentifiableInitializableComponent implements Endpoint {
+
/** {@inheritDoc} */
@Nonnull public DDF receive(@Nonnull final DDF input) throws RemoteProcessingException {
ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this);
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/remoting/AbstractEndpoint.java b/sp-server-api/src/main/java/net/shibboleth/sp/remoting/ApplicationEndpoint.java
similarity index 55%
copy from sp-server-api/src/main/java/net/shibboleth/sp/remoting/AbstractEndpoint.java
copy to sp-server-api/src/main/java/net/shibboleth/sp/remoting/ApplicationEndpoint.java
index 2dbe6ef..b60b91f 100644
--- a/sp-server-api/src/main/java/net/shibboleth/sp/remoting/AbstractEndpoint.java
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/remoting/ApplicationEndpoint.java
@@ -17,26 +17,29 @@ package net.shibboleth.sp.remoting;
import javax.annotation.Nonnull;
-import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
-import net.shibboleth.utilities.java.support.component.ComponentSupport;
+import net.shibboleth.sp.Application;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
import net.shibboleth.utilities.java.support.ddf.DDF;
-import net.shibboleth.utilities.java.support.logic.Constraint;
/**
- * Simple {@link Endpoint} implementation.
+ * Objects implement this interface to receive messages from SP agents scoped by specific
+ * {@link Application} instances.
*/
-public abstract class AbstractEndpoint extends AbstractInitializableComponent implements Endpoint {
+public interface ApplicationEndpoint {
+
+ /**
+ * Gets the messaging address of this component to allow it to receive messages intended for it
+ * to process.
+ *
+ * <p>Addresses must be unique but also "knowable" from the configuration so that SP agents understand
+ * how to issue requests to the service.</p>
+ *
+ * @return a unique address to allow messages to be routed to this component
+ */
+ @Nonnull @NotEmpty String getAddress();
- /** {@inheritDoc} */
- @Nonnull public DDF receive(@Nonnull final DDF input) throws RemoteProcessingException {
- ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this);
- Constraint.isTrue(getAddress().equals(input.name()), "Address was invalid");
-
- return doReceive(input);
- }
-
/**
- * Subclasses should override this method.
+ * Receive a message to process and return the result.
*
* <p>Implementations of this method should catch any checked exceptions and wrap them
* in the {@link RemoteProcessingException} type.</p>
@@ -44,12 +47,14 @@ public abstract class AbstractEndpoint extends AbstractInitializableComponent im
* <p>Unchecked exceptions MAY be surfaced safely and will be caught by the standard error
* handling, so they should be processed internally if that is not the desired behavior.</p>
*
+ * @param application the {@link Application} instance processing the request
* @param input input message
*
* @return output message
*
* @throws RemoteProcessingException if an exception occurs
*/
- @Nonnull abstract public DDF doReceive(@Nonnull final DDF input) throws RemoteProcessingException;
-
+ @Nonnull DDF receive(@Nonnull final Application application, @Nonnull final DDF input)
+ throws RemoteProcessingException;
+
}
\ No newline at end of file
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/remoting/EndpointManager.java b/sp-server-api/src/main/java/net/shibboleth/sp/remoting/ApplicationEndpointManager.java
similarity index 66%
copy from sp-server-api/src/main/java/net/shibboleth/sp/remoting/EndpointManager.java
copy to sp-server-api/src/main/java/net/shibboleth/sp/remoting/ApplicationEndpointManager.java
index fd16e34..9adc4bd 100644
--- a/sp-server-api/src/main/java/net/shibboleth/sp/remoting/EndpointManager.java
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/remoting/ApplicationEndpointManager.java
@@ -25,23 +25,19 @@ import net.shibboleth.utilities.java.support.component.InitializableComponent;
import net.shibboleth.utilities.java.support.component.UnmodifiableComponent;
/**
- * Handles message dispatch to {@link Endpoint} objects that implemenat actual business logic.
- *
- * <p>There may be a way to utilize Spring Integration message routing for this, but I was
- * unable to see an obvious way to use the simple TCP gateway design to dispatch to
- * channels dynamically.</p>
+ * Handles message dispatch to {@link ApplicationEndpoint} objects that implement
+ * application-specific business logic.
*/
@ThreadSafe
-public interface EndpointManager extends InitializableComponent, DestructableComponent, IdentifiedComponent,
+public interface ApplicationEndpointManager extends InitializableComponent, DestructableComponent, IdentifiedComponent,
UnmodifiableComponent {
-
+
/**
- * Gets the {@link Endpoint} registered for a particular address.
+ * Gets the {@link ApplicationEndpoint} registered for a particular address.
*
* @param address the message address
*
- * @return the registered {@link Endpoint} or null
+ * @return the registered {@link ApplicationEndpoint} or null
*/
- @Nullable Endpoint getEndpoint(@Nonnull @NotEmpty final String address);
-
+ @Nullable ApplicationEndpoint getApplicationEndpoint(@Nonnull @NotEmpty final String address);
}
\ No newline at end of file
diff --git a/sp-server-api/src/main/java/net/shibboleth/sp/remoting/EndpointManager.java b/sp-server-api/src/main/java/net/shibboleth/sp/remoting/EndpointManager.java
index fd16e34..6e91ac4 100644
--- a/sp-server-api/src/main/java/net/shibboleth/sp/remoting/EndpointManager.java
+++ b/sp-server-api/src/main/java/net/shibboleth/sp/remoting/EndpointManager.java
@@ -25,7 +25,7 @@ import net.shibboleth.utilities.java.support.component.InitializableComponent;
import net.shibboleth.utilities.java.support.component.UnmodifiableComponent;
/**
- * Handles message dispatch to {@link Endpoint} objects that implemenat actual business logic.
+ * Handles message dispatch to {@link Endpoint} objects that implement actual business logic.
*
* <p>There may be a way to utilize Spring Integration message routing for this, but I was
* unable to see an obvious way to use the simple TCP gateway design to dispatch to
diff --git a/sp-server-impl/src/main/java/net/shibboleth/sp/impl/BasicApplication.java b/sp-server-impl/src/main/java/net/shibboleth/sp/impl/BasicApplication.java
new file mode 100644
index 0000000..390beb0
--- /dev/null
+++ b/sp-server-impl/src/main/java/net/shibboleth/sp/impl/BasicApplication.java
@@ -0,0 +1,92 @@
+/*
+ * 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
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 net.shibboleth.sp.impl;
+
+import javax.annotation.Nonnull;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.shibboleth.sp.Application;
+import net.shibboleth.sp.remoting.AbstractEndpoint;
+import net.shibboleth.sp.remoting.ApplicationEndpoint;
+import net.shibboleth.sp.remoting.ApplicationEndpointManager;
+import net.shibboleth.sp.remoting.RemoteProcessingException;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
+import net.shibboleth.utilities.java.support.component.ComponentSupport;
+import net.shibboleth.utilities.java.support.ddf.DDF;
+import net.shibboleth.utilities.java.support.logic.Constraint;
+
+/**
+ * Basic implementation of an {@link Application}.
+ */
+public class BasicApplication extends AbstractEndpoint implements Application {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(BasicApplication.class);
+
+ /** Component endpoints. */
+ @NonnullAfterInit private ApplicationEndpointManager endpointManager;
+
+ /**
+ * Sets the {@link ApplicationEndpointManager} to use.
+ *
+ * @param manager application endpoint manager
+ */
+ public void setEndpointManager(@Nonnull final ApplicationEndpointManager manager) {
+ ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+
+ endpointManager = Constraint.isNotNull(manager, "ApplicationEndpointManager cannot be null");
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
+ if (endpointManager == null) {
+ throw new ComponentInitializationException("ApplicationEndpointManager cannot be null");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Nonnull @NotEmpty public String getAddress() {
+ return getId();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nonnull public DDF doReceive(@Nonnull final DDF input) throws RemoteProcessingException {
+
+ final DDF operation = input.getmember(OPERATION);
+ if (!operation.isstring()) {
+ log.warn("{}: Received message without string-valued {} member", getId(), OPERATION);
+ throw new RemoteProcessingException("No operation found in message");
+ }
+
+ final ApplicationEndpoint endpoint = endpointManager.getApplicationEndpoint(operation.string());
+
+ if (endpoint == null) {
+ log.warn("{}: No registered target for operation {}", getId(), operation.string());
+ throw new RemoteProcessingException("No registered target for operation " + operation.string());
+ }
+
+ return endpoint.receive(this, input);
+ }
+
+}
\ No newline at end of file
diff --git a/sp-server-impl/src/main/java/net/shibboleth/sp/remoting/impl/BasicApplicationEndpointManager.java b/sp-server-impl/src/main/java/net/shibboleth/sp/remoting/impl/BasicApplicationEndpointManager.java
new file mode 100644
index 0000000..b193a05
--- /dev/null
+++ b/sp-server-impl/src/main/java/net/shibboleth/sp/remoting/impl/BasicApplicationEndpointManager.java
@@ -0,0 +1,69 @@
+/*
+ * 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
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 net.shibboleth.sp.remoting.impl;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import net.shibboleth.sp.remoting.ApplicationEndpoint;
+import net.shibboleth.sp.remoting.ApplicationEndpointManager;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
+import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
+import net.shibboleth.utilities.java.support.component.AbstractIdentifiableInitializableComponent;
+
+/**
+ * Simple implementation of {@link ApplicationEndpointManager} that relies on an in-memory map
+ * of auto-wired components.
+ */
+public class BasicApplicationEndpointManager extends AbstractIdentifiableInitializableComponent
+ implements ApplicationEndpointManager {
+
+ /** Class logger. */
+ @Nonnull private final Logger log = LoggerFactory.getLogger(BasicApplicationEndpointManager.class);
+
+ /** Map of auto-wired message sinks. */
+ @Nonnull @NonnullElements Map<String,ApplicationEndpoint> addressMap;
+
+ /**
+ * Constructor.
+ *
+ * @param remotedObjects auto-wired endpoints
+ */
+ @Autowired
+ public BasicApplicationEndpointManager(@Nullable @NonnullElements Collection<ApplicationEndpoint> remotedObjects) {
+ if (remotedObjects != null) {
+ addressMap = remotedObjects.stream().collect(Collectors.toMap(ApplicationEndpoint::getAddress, r -> r));
+ } else {
+ addressMap = Collections.emptyMap();
+ }
+
+ log.debug("Registered addresses: {}", addressMap.keySet());
+ }
+
+ /** {@inheritDoc} */
+ @Nullable public ApplicationEndpoint getApplicationEndpoint(@Nonnull @NotEmpty final String address) {
+ return addressMap.get(address);
+ }
+
+}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list