diff --git a/bundles/org.eclipse.ecf.provider.jaxrs.client/META-INF/MANIFEST.MF b/bundles/org.eclipse.ecf.provider.jaxrs.client/META-INF/MANIFEST.MF index c1d75d54..4825488f 100644 --- a/bundles/org.eclipse.ecf.provider.jaxrs.client/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.ecf.provider.jaxrs.client/META-INF/MANIFEST.MF @@ -5,7 +5,8 @@ Bundle-SymbolicName: org.eclipse.ecf.provider.jaxrs.client Bundle-Version: 1.6.0.qualifier Bundle-Vendor: Eclipse.org - ECF Require-Bundle: org.eclipse.equinox.common, - org.eclipse.ecf + org.eclipse.ecf, + org.eclipse.ecf.osgi.services.remoteserviceadmin;bundle-version="4.6.1102" Import-Package: com.fasterxml.jackson.core;version="2.9.2", com.fasterxml.jackson.databind;version="2.9.2", com.fasterxml.jackson.jaxrs.base;version="2.9.2", @@ -22,7 +23,8 @@ Import-Package: com.fasterxml.jackson.core;version="2.9.2", org.eclipse.ecf.remoteservice.provider;version="1.0.0", org.eclipse.ecf.remoteservice.util;version="8.3.0", org.eclipse.equinox.concurrent.future;version="1.1.0", - org.osgi.framework + org.osgi.framework, + org.osgi.service.remoteserviceadmin;version="1.1.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.ecf.provider.jaxrs.client;version="1.1.0" diff --git a/bundles/org.eclipse.ecf.provider.jaxrs.client/src/org/eclipse/ecf/provider/jaxrs/client/JaxRSClientEndpointDescriptionReader.java b/bundles/org.eclipse.ecf.provider.jaxrs.client/src/org/eclipse/ecf/provider/jaxrs/client/JaxRSClientEndpointDescriptionReader.java new file mode 100644 index 00000000..c1745818 --- /dev/null +++ b/bundles/org.eclipse.ecf.provider.jaxrs.client/src/org/eclipse/ecf/provider/jaxrs/client/JaxRSClientEndpointDescriptionReader.java @@ -0,0 +1,116 @@ +/******************************************************************************* +* Copyright (c) 2020 Patrick Paulin and others. All rights reserved. This +* program and the accompanying materials are made available under the terms of +* the Eclipse Public License v1.0 which accompanies this distribution, and is +* available at http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Patrick Paulin - initial implementation +******************************************************************************/ +package org.eclipse.ecf.provider.jaxrs.client; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.eclipse.ecf.internal.osgi.services.remoteserviceadmin.EndpointDescriptionParser; +import org.eclipse.ecf.osgi.services.remoteserviceadmin.EndpointDescriptionReader; +import org.eclipse.ecf.provider.jaxrs.JaxRSNamespace; +import org.osgi.service.remoteserviceadmin.EndpointDescription; + +/** + * An endpoint reader that sets JAX-RS defaults. These defaults are consistent + * across most clients and should not need to be set in each EDEF file. + * Currently, the only properties that are required in an EDEF file are: + * + * All other properties can be omitted, though they may be set if desired. + *

+ * Note that a reader must be registered as an OSGi service. It is assumed that + * subclasses of this reader will do the actual registration. + */ +@SuppressWarnings("restriction") +public class JaxRSClientEndpointDescriptionReader extends EndpointDescriptionReader { + + @Override + public EndpointDescription[] readEndpointDescriptions(InputStream input, Map overrideProperties) + throws IOException { + + /* + * Need to copy input so that we can pass an unconsumed input to superclass + * method. Otherwise input is consumed when retrieving base endpoint properties. + */ + byte[] inputAsByteArray = getByteArrayFromInput(input); + + Map baseProperties = getBaseEndpointProperties(new ByteArrayInputStream(inputAsByteArray)); + addDefaultsToOverridesIfNeeded(baseProperties, overrideProperties); + + return super.readEndpointDescriptions(new ByteArrayInputStream(inputAsByteArray), overrideProperties); + } + + /** + * Add default property values for JAX-RS clients. Classes that override this + * method should call the superclass method. + */ + protected void addDefaultsToOverridesIfNeeded(Map baseProperties, + Map overrideProperties) { + /* JAX-RS defaults */ + setDefaultPropertyIfNecessary(baseProperties, overrideProperties, + org.eclipse.ecf.osgi.services.remoteserviceadmin.RemoteConstants.ENDPOINT_CONTAINER_ID_NAMESPACE, + JaxRSNamespace.NAME); + setDefaultPropertyIfNecessary(baseProperties, overrideProperties, "remote.intents.supported", + new String[] { "passByValue", "exactlyOnce", "ordered", "jaxrs" }); + setDefaultPropertyIfNecessary(baseProperties, overrideProperties, + org.eclipse.ecf.remoteservice.Constants.OSGI_SERVICE_INTENTS, + new String[] { org.eclipse.ecf.remoteservice.Constants.OSGI_ASYNC_INTENT }); + + /* Defaults that perhaps shouldn't be required for JAX-RS clients */ + setDefaultPropertyIfNecessary(baseProperties, overrideProperties, + org.osgi.service.remoteserviceadmin.RemoteConstants.ENDPOINT_ID, UUID.randomUUID().toString()); + setDefaultPropertyIfNecessary(baseProperties, overrideProperties, + org.eclipse.ecf.remoteservice.Constants.SERVICE_ID, Long.valueOf(0)); + setDefaultPropertyIfNecessary(baseProperties, overrideProperties, + org.eclipse.ecf.remoteservice.Constants.ENDPOINT_REMOTESERVICE_FILTER, "(objectClass=*)"); + } + + protected void setDefaultPropertyIfNecessary(Map baseProperties, + Map overrideProperties, String key, Object defaultValue) { + if (!baseProperties.containsKey(key) && !overrideProperties.containsKey(key)) { + overrideProperties.put(key, defaultValue); + } + } + + private Map getBaseEndpointProperties(InputStream input) throws IOException { + EndpointDescriptionParser parser = new EndpointDescriptionParser(); + parser.parse(input); + + List endpointDescriptions = parser.getEndpointDescriptions(); + + /* + * Returning properties for first endpoint if multiple. Not sure how to apply + * defaults if more than one endpoint in file + */ + if (endpointDescriptions.size() > 0) { + return endpointDescriptions.get(0).getProperties(); + } + return new HashMap(); + } + + private byte[] getByteArrayFromInput(InputStream input) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int n = 0; + while ((n = input.read(buffer)) >= 0) + baos.write(buffer, 0, n); + input.close(); + + return baos.toByteArray(); + } +} \ No newline at end of file diff --git a/bundles/org.eclipse.ecf.provider.jersey.client/META-INF/MANIFEST.MF b/bundles/org.eclipse.ecf.provider.jersey.client/META-INF/MANIFEST.MF index 7e7ae595..6e652c59 100644 --- a/bundles/org.eclipse.ecf.provider.jersey.client/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.ecf.provider.jersey.client/META-INF/MANIFEST.MF @@ -14,6 +14,7 @@ Import-Package: com.fasterxml.jackson.core;version="2.9.2", javax.ws.rs.client;version="2.0.1", javax.ws.rs.core;version="2.0.1", javax.ws.rs.ext;version="2.0.1", + org.eclipse.ecf.osgi.services.remoteserviceadmin;version="1.3.0", org.eclipse.ecf.provider.jaxrs;version="1.0.0", org.eclipse.ecf.provider.jaxrs.client;version="1.1.0", org.eclipse.ecf.remoteservice;version="7.2.0", @@ -25,10 +26,12 @@ Import-Package: com.fasterxml.jackson.core;version="2.9.2", org.glassfish.jersey.client;version="2.14.0", org.glassfish.jersey.jackson;version="2.14.0", org.osgi.framework, - org.osgi.service.component.annotations;version="1.2.0";resolution:=optional + org.osgi.service.component.annotations;version="1.2.0";resolution:=optional, + org.osgi.service.remoteserviceadmin;version="1.1.0" Require-Bundle: org.eclipse.ecf, org.eclipse.equinox.common Provide-Capability: osgi.remoteserviceadmin.distribution; configs:List="ecf.jaxrs.jersey.client"; version:Version=1.0 Export-Package: org.eclipse.ecf.provider.jersey.client;version="1.1.0" Automatic-Module-Name: org.eclipse.ecf.provider.jersey.client -Service-Component: OSGI-INF/org.eclipse.ecf.provider.jersey.client.JerseyClientDistributionProvider.xml +Service-Component: OSGI-INF/org.eclipse.ecf.provider.jersey.client.JerseyClientDistributionProvider.xml, + OSGI-INF/org.eclipse.ecf.provider.jersey.client.JerseyClientEndpointDescriptionReader.xml diff --git a/bundles/org.eclipse.ecf.provider.jersey.client/OSGI-INF/org.eclipse.ecf.provider.jersey.client.JerseyClientEndpointDescriptionReader.xml b/bundles/org.eclipse.ecf.provider.jersey.client/OSGI-INF/org.eclipse.ecf.provider.jersey.client.JerseyClientEndpointDescriptionReader.xml new file mode 100644 index 00000000..0a36d7e8 --- /dev/null +++ b/bundles/org.eclipse.ecf.provider.jersey.client/OSGI-INF/org.eclipse.ecf.provider.jersey.client.JerseyClientEndpointDescriptionReader.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/bundles/org.eclipse.ecf.provider.jersey.client/src/org/eclipse/ecf/provider/jersey/client/JerseyClientEndpointDescriptionReader.java b/bundles/org.eclipse.ecf.provider.jersey.client/src/org/eclipse/ecf/provider/jersey/client/JerseyClientEndpointDescriptionReader.java new file mode 100644 index 00000000..001c2fbc --- /dev/null +++ b/bundles/org.eclipse.ecf.provider.jersey.client/src/org/eclipse/ecf/provider/jersey/client/JerseyClientEndpointDescriptionReader.java @@ -0,0 +1,33 @@ +/******************************************************************************* +* Copyright (c) 2020 Patrick Paulin and others. All rights reserved. This +* program and the accompanying materials are made available under the terms of +* the Eclipse Public License v1.0 which accompanies this distribution, and is +* available at http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* Patrick Paulin - initial implementation +******************************************************************************/ +package org.eclipse.ecf.provider.jersey.client; + +import java.util.Map; + +import org.eclipse.ecf.osgi.services.remoteserviceadmin.IEndpointDescriptionReader; +import org.eclipse.ecf.provider.jaxrs.client.JaxRSClientEndpointDescriptionReader; +import org.osgi.service.component.annotations.Component; + +/** + * This extension adds defaults specific to Jersey and also registers the reader + * as an OSGi service. This reader should be picked up first by the ECF + * framework because the default reader is registered with the minimum service + * ranking. + */ +@Component(service = IEndpointDescriptionReader.class) +public class JerseyClientEndpointDescriptionReader extends JaxRSClientEndpointDescriptionReader { + + protected void addDefaultsToOverridesIfNeeded(Map baseProperties, + Map overrideProperties) { + super.addDefaultsToOverridesIfNeeded(baseProperties, overrideProperties); + setDefaultPropertyIfNecessary(baseProperties, overrideProperties, "service.imported.configs", + new String[] { JerseyClientDistributionProvider.SERVER_PROVIDER_NAME }); + } +}