diff --git a/CHANGELOG.md b/CHANGELOG.md
index ffe275949..1873f1be6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,9 +9,13 @@
### Deprecated
### Removed
+
- Dependency to deprecated oslc4j-json4j-provider
+
### Fixed
+- Client now picks the correct ResponseInfo object when an OSLC Query response contains multiple ResponseInfo objects.
+
## [6.0.0]
### Security
diff --git a/client/oslc-client/src/main/java/org/eclipse/lyo/client/query/OslcQueryResult.java b/client/oslc-client/src/main/java/org/eclipse/lyo/client/query/OslcQueryResult.java
index 5654c10c7..04094c85f 100644
--- a/client/oslc-client/src/main/java/org/eclipse/lyo/client/query/OslcQueryResult.java
+++ b/client/oslc-client/src/main/java/org/eclipse/lyo/client/query/OslcQueryResult.java
@@ -13,14 +13,7 @@
*/
package org.eclipse.lyo.client.query;
-import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import javax.xml.datatype.DatatypeConfigurationException;
-
+import jakarta.ws.rs.core.Response;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.rdf.model.Property;
@@ -37,213 +30,337 @@
import org.eclipse.lyo.oslc4j.core.exception.OslcCoreApplicationException;
import org.eclipse.lyo.oslc4j.core.model.OslcConstants;
import org.eclipse.lyo.oslc4j.provider.jena.JenaModelHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import jakarta.ws.rs.core.Response;
+import javax.xml.datatype.DatatypeConfigurationException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
/**
- * The results of an OSLC query. If the query was paged, subsequent pages can be retrieved using the Iterator interface.
- *
+ * The results of an OSLC query. If the query was paged, subsequent pages can be retrieved using
+ * the Iterator interface.
+ *
* This class is not currently thread safe.
*/
public class OslcQueryResult implements Iterator {
- /**
- * The default member property to look for in OSLC query results
- * (rdfs:member). Can be changed using {@link #setMemberProperty(String)}.
- */
- public final static Property DEFAULT_MEMBER_PROPERTY = RDFS.member;
-
- /**
- * If system property {@value} is set to true, find any member in the
- */
- public final static String SELECT_ANY_MEMBER = "org.eclipse.lyo.client.oslc.query.selectAnyMember";
-
- /**
- * Treat any resource in the members resource as a query result (except rdf:type).
- *
- * @see OslcQueryResult#SELECT_ANY_MEMBER
- */
- private final class AnyMemberSelector extends SimpleSelector {
- private AnyMemberSelector(Resource subject) {
- super(subject, null, (RDFNode) null);
- }
-
- public boolean selects(Statement s) {
- String fqPredicateName = s.getPredicate().getNameSpace() + s.getPredicate().getLocalName();
- if (OSLCConstants.RDF_TYPE_PROP.equals(fqPredicateName)) {
- return false;
- }
-
- return s.getObject().isResource();
- }
+ private static final Logger log = LoggerFactory.getLogger(OslcQueryResult.class);
+ /**
+ * The default member property to look for in OSLC query results
+ * (rdfs:member). Can be changed using {@link #setMemberProperty(String)}.
+ */
+ public final static Property DEFAULT_MEMBER_PROPERTY = RDFS.member;
+
+ /**
+ * If system property {@value} is set to true, find any member in the
+ */
+ public final static String SELECT_ANY_MEMBER = "org.eclipse.lyo.client.oslc.query" +
+ ".selectAnyMember";
+
+ /**
+ * Treat any resource in the members resource as a query result (except rdf:type).
+ *
+ * @see OslcQueryResult#SELECT_ANY_MEMBER
+ */
+ private final class AnyMemberSelector extends SimpleSelector {
+ private AnyMemberSelector(Resource subject) {
+ super(subject, null, (RDFNode) null);
+ }
+
+ public boolean selects(Statement s) {
+ String fqPredicateName =
+ s.getPredicate().getNameSpace() + s.getPredicate().getLocalName();
+ if (OSLCConstants.RDF_TYPE_PROP.equals(fqPredicateName)) {
+ return false;
+ }
+
+ return s.getObject().isResource();
+ }
+ }
+
+ private final OslcQuery query;
+
+ private final Response response;
+
+ private final int pageNumber;
+
+ private Property memberProperty = DEFAULT_MEMBER_PROPERTY;
+
+ private Model rdfModel;
+
+ private Resource infoResource, membersResource;
+
+ private String nextPageUrl = "";
+
+ private boolean rdfInitialized = false;
+
+ public OslcQueryResult(OslcQuery query, Response response) {
+ this.query = query;
+ this.response = response;
+
+ this.pageNumber = 1;
+
+
+ }
+
+ private OslcQueryResult(OslcQueryResult prev) {
+ this.query = new OslcQuery(prev);
+ this.response = this.query.getResponse();
+ this.membersResource = prev.membersResource;
+ this.memberProperty = prev.memberProperty;
+
+ this.pageNumber = prev.pageNumber + 1;
+
+ }
+
+ private synchronized void initializeRdf() {
+ if (!rdfInitialized) {
+ rdfInitialized = true;
+ rdfModel = ModelFactory.createDefaultModel();
+ rdfModel.read(response.readEntity(InputStream.class), query.getCapabilityUrl());
+
+ //Find a resource with rdf:type of oslc:ResourceInfo
+ Property rdfType = rdfModel.createProperty(OslcConstants.RDF_NAMESPACE, "type");
+ Property responseInfo = rdfModel.createProperty(OslcConstants.OSLC_CORE_NAMESPACE,
+ "ResponseInfo");
+ ResIterator iter = rdfModel.listResourcesWithProperty(rdfType, responseInfo);
+
+ //The main ResponseInfo shall have the query URI or a page URI
+ List responseInfos = iter.toList();
+
+ infoResource = null;
+ membersResource = rdfModel.getResource(query.getCapabilityUrl());
+
+ if (responseInfos.isEmpty()) {
+ return;
+ }
+
+ infoResource = tryFindOnlyResponseInfo(responseInfos);
+ if (infoResource == null) {
+ log.trace("Cannot find exactly one ResponseInfo");
+ } else {
+ log.debug("Found exactly one ResponseInfo");
+ return;
+ }
+
+ infoResource = tryFindOnlyWithNextPage(responseInfos);
+ if (infoResource == null) {
+ log.trace("Cannot find exactly one ResponseInfo with nextPage");
+ } else {
+ log.debug("Found exactly one ResponseInfo with nextPage");
+ return;
+ }
+
+ infoResource = tryFindExactResponseInfoUri(responseInfos);
+ if (infoResource == null) {
+ log.trace("Cannot a ResponseInfo whose URI matches the query URI exactly");
+ } else {
+ log.debug("Found a ResponseInfo whose URI matches the query URI exactly");
+ return;
+ }
+
+ infoResource = tryFindPrefixedResponseInfoUri(responseInfos);
+ if (infoResource == null) {
+ log.trace("Cannot find exactly one ResponseInfo whose URI starts with the query URI");
+ } else {
+ log.debug("Found exactly one ResponseInfo whose URI starts with the query URI");
+ return;
+ }
+
+ if (infoResource == null) {
+ throw new IllegalStateException("Failed to find an appropriate ResponseInfo object");
+ }
+
+ }
+ }
+
+ /**
+ * Extracts a ResourceInfo resource if one and only one has a property with the nextPage
+ * predicate.
+ *
+ * @param responseInfos from OSLC Query results
+ * @return a ResourceInfo resource if one satisfies the conditions; null if none satisfy
+ */
+ private Resource tryFindOnlyWithNextPage(List responseInfos) {
+ Property nextPagePredicate = rdfModel.getProperty(OslcConstants.OSLC_CORE_NAMESPACE,
+ "nextPage");
+ var responsesWithNextPage =
+ responseInfos.stream().filter(ri -> ri.getProperty(nextPagePredicate) != null).toList();
+ if (responsesWithNextPage.size() == 1) {
+ return responsesWithNextPage.get(0);
+ }
+ else if (responsesWithNextPage.size() > 1) {
+ log.warn("Multiple ResponseInfo objects found with nextPage predicate");
+ }
+ return null;
}
- private final OslcQuery query;
-
- private final Response response;
-
- private final int pageNumber;
-
- private Property memberProperty = DEFAULT_MEMBER_PROPERTY;
-
- private Model rdfModel;
-
- private Resource infoResource, membersResource;
-
- private String nextPageUrl = "";
-
- private boolean rdfInitialized = false;
-
- public OslcQueryResult(OslcQuery query, Response response) {
- this.query = query;
- this.response = response;
-
- this.pageNumber = 1;
-
-
- }
-
- private OslcQueryResult(OslcQueryResult prev) {
- this.query = new OslcQuery(prev);
- this.response = this.query.getResponse();
- this.membersResource = prev.membersResource;
- this.memberProperty = prev.memberProperty;
-
- this.pageNumber = prev.pageNumber + 1;
-
- }
-
- private synchronized void initializeRdf() {
- if (!rdfInitialized) {
- rdfInitialized = true;
- rdfModel = ModelFactory.createDefaultModel();
- rdfModel.read(response.readEntity(InputStream.class), query.getCapabilityUrl());
-
- //Find a resource with rdf:type of oslc:ResourceInfo
- Property rdfType = rdfModel.createProperty(OslcConstants.RDF_NAMESPACE, "type");
- Property responseInfo = rdfModel.createProperty(OslcConstants.OSLC_CORE_NAMESPACE, "ResponseInfo");
- ResIterator iter = rdfModel.listResourcesWithProperty(rdfType, responseInfo);
-
- //There should only be one - take the first
- infoResource = null;
- while (iter.hasNext()) {
- infoResource = iter.next();
- break;
- }
- membersResource = rdfModel.getResource(query.getCapabilityUrl());
- }
- }
-
- String getNextPageUrl() {
- initializeRdf();
- if ((nextPageUrl == null || nextPageUrl.isEmpty()) && infoResource != null) {
- Property predicate = rdfModel.getProperty(OslcConstants.OSLC_CORE_NAMESPACE, "nextPage");
- Selector select = new SimpleSelector(infoResource, predicate, (RDFNode) null);
- StmtIterator iter = rdfModel.listStatements(select);
- if (iter.hasNext()) {
- Statement nextPage = iter.next();
- nextPageUrl = nextPage.getResource().getURI();
- } else {
- nextPageUrl = "";
- }
- }
- return nextPageUrl;
- }
-
- /**
- * @return whether there is another page of results after this
- */
- public boolean hasNext() {
- return (!"".equals(getNextPageUrl()));
- }
-
- /**
- * @return the next page of results
- */
- public OslcQueryResult next() {
- return new OslcQueryResult(this);
- }
-
- /**
- * @throws UnsupportedOperationException always
- */
- public void remove() {
- throw new UnsupportedOperationException();
- }
-
- public OslcQuery getQuery() {
- return query;
- }
-
- /**
- * Returns the member property to find query result resources.
- *
- * @return the member property URI
- * @see #setMemberProperty(String)
- */
- public String getMemberProperty() {
- return this.memberProperty.getURI();
- }
-
- /**
- * Sets the predicate to use to find query result resources. If unset,
- * defaults to {@code http://www.w3.org/2000/01/rdf-schema#member}.
- *
- * @param memberPredicate
- * the RDF predicate for member resources from the provider's
- * query shape
- * @see Specifying the sahpe of a query
- */
- public void setMemberProperty(String memberPredicate) {
- this.memberProperty = ModelFactory.createDefaultModel().createProperty(memberPredicate);
- }
-
- /**
- * Get the raw Wink client response to a query.
- *
- * NOTE: Using this method and consuming the response will make other methods
- * which examine the response unavailable (Examples: getMemberUrls(), next() and hasNext()).
- * When this method is invoked, the consumer is responsible for OSLC page processing
- *
- * @return
- */
- public Response getRawResponse() {
- return response;
- }
-
- private Selector getMemberSelector() {
- if ("true".equalsIgnoreCase(System.getProperty(SELECT_ANY_MEMBER))) {
- return new AnyMemberSelector(membersResource);
- }
-
- return new SimpleSelector(membersResource, memberProperty, (RDFNode) null);
- }
-
- /**
- * Return the subject URLs of the query response. The URLs are the location of all artifacts
- * which satisfy the query conditions.
- *
- * NOTE: Using this method consumes the query response and makes other methods
- * which examine the response unavailable (Example: getRawResponse().
- * @return
- */
- public String[] getMembersUrls() {
- initializeRdf();
- ArrayList membersUrls = new ArrayList<>();
+ /**
+ * Extracts a ResourceInfo resource if one and only one has the same prefix as the query URI.
+ *
+ * @param responseInfos from OSLC Query results
+ * @return a ResourceInfo resource if one satisfies the conditions; null if none satisfy
+ */
+ private Resource tryFindPrefixedResponseInfoUri(List responseInfos) {
+ List filteredObjects =
+ responseInfos.stream().filter(ri -> ri.getURI().startsWith(query.getQueryUrl())).toList();
+ if (filteredObjects.size() == 1) {
+ return filteredObjects.get(0);
+ } else if (filteredObjects.size() > 1) {
+ log.warn("Multiple ResponseInfo objects found starting with the same Query URI");
+ }
+ return null;
+ }
+
+ /**
+ * Extracts a ResourceInfo resource if one and only one has exactly the same URI as the query
+ * URI.
+ *
+ * @param responseInfos from OSLC Query results
+ * @return a ResourceInfo resource if one satisfies the conditions; null if none satisfy
+ * @throws IllegalStateException if multiple resources satisfy the same condition
+ */
+ private Resource tryFindExactResponseInfoUri(List responseInfos) {
+ List filteredObjects =
+ responseInfos.stream().filter(ri -> ri.getURI().equals(query.getQueryUrl())).toList();
+ if (filteredObjects.size() == 1) {
+ return filteredObjects.get(0);
+ } else if (filteredObjects.size() > 1) {
+ throw new IllegalStateException("Multiple ResponseInfo objects found with the same URI");
+ }
+ return null;
+ }
+
+ /**
+ * Extracts a ResourceInfo resource if one and only one exists in the results.
+ *
+ * @param responseInfos from OSLC Query results
+ * @return a ResourceInfo resource if one satisfies the conditions; null if none satisfy
+ */
+ private Resource tryFindOnlyResponseInfo(List responseInfos) {
+ if (responseInfos.size() == 1) {
+ return responseInfos.get(0);
+ }
+ return null;
+ }
+
+ String getNextPageUrl() {
+ initializeRdf();
+ if ((nextPageUrl == null || nextPageUrl.isEmpty()) && infoResource != null) {
+ Property predicate = rdfModel.getProperty(OslcConstants.OSLC_CORE_NAMESPACE,
+ "nextPage");
+ Selector select = new SimpleSelector(infoResource, predicate, (RDFNode) null);
+ StmtIterator iter = rdfModel.listStatements(select);
+ if (iter.hasNext()) {
+ Statement nextPage = iter.next();
+ nextPageUrl = nextPage.getResource().getURI();
+ } else {
+ nextPageUrl = "";
+ }
+ }
+ return nextPageUrl;
+ }
+
+ /**
+ * @return whether there is another page of results after this
+ */
+ public boolean hasNext() {
+ return (!"".equals(getNextPageUrl()));
+ }
+
+ /**
+ * @return the next page of results
+ */
+ public OslcQueryResult next() {
+ return new OslcQueryResult(this);
+ }
+
+ /**
+ * @throws UnsupportedOperationException always
+ */
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ public OslcQuery getQuery() {
+ return query;
+ }
+
+ /**
+ * Returns the member property to find query result resources.
+ *
+ * @return the member property URI
+ * @see #setMemberProperty(String)
+ */
+ public String getMemberProperty() {
+ return this.memberProperty.getURI();
+ }
+
+ /**
+ * Sets the predicate to use to find query result resources. If unset,
+ * defaults to {@code http://www.w3.org/2000/01/rdf-schema#member}.
+ *
+ * @param memberPredicate the RDF predicate for member resources from the provider's
+ * query shape
+ * @see
+ * Specifying the sahpe of a query
+ */
+ public void setMemberProperty(String memberPredicate) {
+ this.memberProperty = ModelFactory.createDefaultModel().createProperty(memberPredicate);
+ }
+
+ /**
+ * Get the raw Wink client response to a query.
+ *
+ * NOTE: Using this method and consuming the response will make other methods
+ * which examine the response unavailable (Examples: getMemberUrls(), next() and hasNext()).
+ * When this method is invoked, the consumer is responsible for OSLC page processing
+ *
+ * @return
+ */
+ public Response getRawResponse() {
+ return response;
+ }
+
+ private Selector getMemberSelector() {
+ if ("true".equalsIgnoreCase(System.getProperty(SELECT_ANY_MEMBER))) {
+ return new AnyMemberSelector(membersResource);
+ }
+
+ return new SimpleSelector(membersResource, memberProperty, (RDFNode) null);
+ }
+
+ /**
+ * Return the subject URLs of the query response. The URLs are the location of all artifacts
+ * which satisfy the query conditions.
+ *
+ * NOTE: Using this method consumes the query response and makes other methods
+ * which examine the response unavailable (Example: getRawResponse().
+ *
+ * @return
+ */
+ public String[] getMembersUrls() {
+ initializeRdf();
+ ArrayList membersUrls = new ArrayList<>();
Selector select = getMemberSelector();
- StmtIterator iter = rdfModel.listStatements(select);
- while (iter.hasNext()) {
- Statement member = iter.next();
- membersUrls.add(member.getResource().getURI());
- }
- return membersUrls.toArray(new String[membersUrls.size()]);
- }
-
- /**
- * Return the enumeration of queried results from this page
- *
- * @return member statements from current page.
- */
+ StmtIterator iter = rdfModel.listStatements(select);
+ while (iter.hasNext()) {
+ Statement member = iter.next();
+ membersUrls.add(member.getResource().getURI());
+ }
+ return membersUrls.toArray(new String[membersUrls.size()]);
+ }
+
+ /**
+ * Return the enumeration of queried results from this page
+ *
+ * @return member statements from current page.
+ */
public Iterable getMembers(final Class clazz) {
initializeRdf();
@@ -259,11 +376,12 @@ public T next() {
Statement member = iter.next();
try {
- return (T) JenaModelHelper.fromJenaResource((Resource) member.getObject(), clazz);
+ return (T) JenaModelHelper.fromJenaResource((Resource) member.getObject(),
+ clazz);
} catch (DatatypeConfigurationException | IllegalAccessException |
InvocationTargetException | InstantiationException |
- OslcCoreApplicationException
- | NoSuchMethodException | URISyntaxException e) {
+ OslcCoreApplicationException | NoSuchMethodException |
+ URISyntaxException e) {
throw new LyoModelException(e);
}
}
diff --git a/client/oslc-client/src/test/java/org/eclipse/lyo/client/OslcClientTest.java b/client/oslc-client/src/test/java/org/eclipse/lyo/client/OslcClientTest.java
index f84966671..5a84d94d1 100644
--- a/client/oslc-client/src/test/java/org/eclipse/lyo/client/OslcClientTest.java
+++ b/client/oslc-client/src/test/java/org/eclipse/lyo/client/OslcClientTest.java
@@ -1,53 +1,57 @@
/*
- * Copyright (c) 2021 Contributors to the Eclipse Foundation See the NOTICE file(s) distributed with this work for
- * additional information regarding copyright ownership. This program and the accompanying materials are made available
- * under the terms of the Eclipse Public License 2.0 which is available at http://www.eclipse.org/legal/epl-2.0, or the
- * Eclipse Distribution License 1.0 which is available at http://www.eclipse.org/org/documents/edl-v10.php.
+ * Copyright (c) 2021 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License 1.0
+ * which is available at http://www.eclipse.org/org/documents/edl-v10.php.
+ *
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
package org.eclipse.lyo.client;
-import static java.time.Duration.ofSeconds;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.assertNull;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTimeout;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.util.Map;
-
-import javax.xml.namespace.QName;
-
+import jakarta.ws.rs.client.Invocation.Builder;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status.Family;
import org.apache.http.HttpHeaders;
import org.eclipse.lyo.oslc4j.core.model.ServiceProvider;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
-import jakarta.ws.rs.client.Invocation.Builder;
-import jakarta.ws.rs.core.Response;
-import jakarta.ws.rs.core.Response.Status.Family;
+import javax.xml.namespace.QName;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Map;
+
+import static java.time.Duration.*;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
public class OslcClientTest {
- /*
- * Tests that the RDF/XML MessageBodyWriter doesn't go into an infinite loop when given bad data on the client (Bug
- * 417749). ClientRuntimeException no longer expected in Lyo 4.0.
+ /**
+ * Tests that the RDF/XML MessageBodyWriter doesn't go into an infinite loop when
+ * given bad data on the client (Bug 417749). ClientRuntimeException no longer expected in
+ * Lyo 4.0.
*/
- // @Disabled("Unit test actually POSTs data to example.com, which we shouldn't do as we don't own that domain.")
+// @Disabled("Unit test actually POSTs data to example.com, which we shouldn't do as we don't
+// own that domain.")
@Test
public void postInvalidOlscResource() throws IOException, URISyntaxException {
assertTimeout(ofSeconds(10), () -> {
final OslcClient client = new OslcClient();
final ServiceProvider request = new ServiceProvider();
- request.getExtendedProperties().put(new QName("http://example.com/ns#", "test"), "test");
- Response response = client.createResource(
- "http://open-services.net/.well-known/resource-that-should-not-exist-whose-status-code-should-not-be-200",
- request, OSLCConstants.CT_RDF);
+ request.getExtendedProperties().put(new QName("http://example.com/ns#", "test"),
+ "test");
+ Response response = client.createResource("http://open-services.net/" +
+ ".well-known/resource-that-should-not-exist-whose-status-code-should-not-be-200",
+ request, OSLCConstants.CT_RDF);
assertThat(response.getStatusInfo().getFamily() != Family.SUCCESSFUL);
// assertThrows(ClientErrorException.class, () -> {
//
@@ -64,7 +68,7 @@ public void initTest() {
@Test
public void connectionTest() {
final OslcClient client = new OslcClient();
- final Response resource = client.getResource("http://open-services.net");
+ final Response resource = client.getResource("https://open-services.net");
assertThat(resource).isNotNull();
assertThat(resource.getStatus()).isLessThan(400);
}
@@ -72,72 +76,84 @@ public void connectionTest() {
@Test
public void testGetResource() {
OslcClient client = mock(OslcClient.class, Mockito.CALLS_REAL_METHODS);
- doReturn(null).when(client).doRequest(any(), any(), any(), any(), any(), any(), any(), any());
+ doReturn(null).when(client).doRequest(any(), any(), any(), any(), any(), any(), any(),
+ any());
client.getResource("test.url");
- verify(client).doRequest("GET", "test.url", null, null, null, null, "application/rdf+xml", null);
+ verify(client).doRequest("GET", "test.url", null, null, null, null, "application/rdf+xml"
+ , null);
clearInvocations(client);
client.getResource("test.url", "application/rdf+xml");
- verify(client).doRequest("GET", "test.url", null, null, null, "application/rdf+xml", "application/rdf+xml",
- null);
+ verify(client).doRequest("GET", "test.url", null, null, null, "application/rdf+xml",
+ "application/rdf+xml", null);
clearInvocations(client);
client.getResource("test.url", Map.of("a", "b"), "application/rdf+xml", "oslc.context");
- verify(client).doRequest("GET", "test.url", null, "oslc.context", null, "application/rdf+xml",
- "application/rdf+xml", Map.of("a", "b"));
+ verify(client).doRequest("GET", "test.url", null, "oslc.context", null, "application/rdf" +
+ "+xml", "application/rdf+xml", Map.of("a", "b"));
}
@Test
public void testPutResource() {
OslcClient client = mock(OslcClient.class, Mockito.CALLS_REAL_METHODS);
- doReturn(null).when(client).doRequest(any(), any(), any(), any(), any(), any(), any(), any());
+ doReturn(null).when(client).doRequest(any(), any(), any(), any(), any(), any(), any(),
+ any());
client.updateResource("test.url", "artifact", "application/json");
- verify(client).doRequest("PUT", "test.url", "artifact", null, null, "application/json", "*/*", null);
+ verify(client).doRequest("PUT", "test.url", "artifact", null, null, "application/json",
+ "*/*", null);
clearInvocations(client);
- client.updateResource("test.url", "artifact", "application/json", "*/*", "ifmatch", "configContext");
- verify(client).doRequest("PUT", "test.url", "artifact", "configContext", "ifmatch", "application/json", "*/*",
- null);
+ client.updateResource("test.url", "artifact", "application/json", "*/*", "ifmatch",
+ "configContext");
+ verify(client).doRequest("PUT", "test.url", "artifact", "configContext", "ifmatch",
+ "application/json", "*/*", null);
clearInvocations(client);
client.updateResource("test.url", "artifact", "application/json", "*/*", "ifmatch");
- verify(client).doRequest("PUT", "test.url", "artifact", null, "ifmatch", "application/json", "*/*", null);
+ verify(client).doRequest("PUT", "test.url", "artifact", null, "ifmatch", "application" +
+ "/json", "*/*", null);
}
@Test
public void testDeleteResource() {
OslcClient client = mock(OslcClient.class, Mockito.CALLS_REAL_METHODS);
- doReturn(null).when(client).doRequest(any(), any(), any(), any(), any(), any(), any(), any());
+ doReturn(null).when(client).doRequest(any(), any(), any(), any(), any(), any(), any(),
+ any());
client.deleteResource("test.url");
verify(client).doRequest("DELETE", "test.url", null, null, null, null, null, null);
clearInvocations(client);
client.deleteResource("test.url", "configContext");
- verify(client).doRequest("DELETE", "test.url", null, "configContext", null, null, null, null);
+ verify(client).doRequest("DELETE", "test.url", null, "configContext", null, null, null,
+ null);
}
@Test
public void testCreateResource() {
OslcClient client = mock(OslcClient.class, Mockito.CALLS_REAL_METHODS);
- doReturn(null).when(client).doRequest(any(), any(), any(), any(), any(), any(), any(), any());
+ doReturn(null).when(client).doRequest(any(), any(), any(), any(), any(), any(), any(),
+ any());
client.createResource("test.url", "artifact", "application/rdf+xml");
- verify(client).doRequest("POST", "test.url", "artifact", null, null, "application/rdf+xml", "*/*", null);
+ verify(client).doRequest("POST", "test.url", "artifact", null, null, "application/rdf+xml"
+ , "*/*", null);
clearInvocations(client);
client.createResource("test.url", "artifact", "application/rdf+xml", "*/*", "oslc.ctx");
- verify(client).doRequest("POST", "test.url", "artifact", "oslc.ctx", null, "application/rdf+xml", "*/*", null);
+ verify(client).doRequest("POST", "test.url", "artifact", "oslc.ctx", null, "application" +
+ "/rdf+xml", "*/*", null);
}
@Test
public void testAddHeaders() {
OslcClient client = new OslcClient();
Builder builder = mock(Builder.class);
- Map headers = client.addHeaders(builder, Map.of("a", "b"), "ifmatch", "ctx");
+ Map headers = client.addHeaders(builder, Map.of("a", "b"), "ifmatch",
+ "ctx");
assertEquals(4, headers.size());
assertEquals("b", headers.get("a"));
diff --git a/client/oslc-client/src/test/java/org/eclipse/lyo/client/OslcQueryResultTest.java b/client/oslc-client/src/test/java/org/eclipse/lyo/client/OslcQueryResultTest.java
deleted file mode 100644
index 1c289a5ed..000000000
--- a/client/oslc-client/src/test/java/org/eclipse/lyo/client/OslcQueryResultTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2020 Contributors to the Eclipse Foundation
- *
- * See the NOTICE file(s) distributed with this work for additional
- * information regarding copyright ownership.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License 2.0 which is available at
- * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License 1.0
- * which is available at http://www.eclipse.org/org/documents/edl-v10.php.
- *
- * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
- */
-package org.eclipse.lyo.client;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.when;
-
-import java.io.InputStream;
-
-import org.eclipse.lyo.client.query.OslcQuery;
-import org.eclipse.lyo.client.query.OslcQueryParameters;
-import org.eclipse.lyo.client.query.OslcQueryResult;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import jakarta.ws.rs.core.Response;
-
-/**
- * @author Samuel Padgett
- */
-public class OslcQueryResultTest {
- @Before
- public void clearPublicURISystemProperty() {
- System.clearProperty(OslcQueryResult.SELECT_ANY_MEMBER);
- }
-
- @Test
- public void testEmpty() {
- Response mockedResponse = mockClientResponse("/emptyQuery.rdf");
-
- OslcQueryParameters params = new OslcQueryParameters();
- params.setWhere("dceterms:identifier=3");
- OslcQuery query = new OslcQuery(new OslcClient(), "http://example.com/provider/query", params);
- OslcQueryResult result = new OslcQueryResult(query, mockedResponse);
- assertEquals(0, result.getMembersUrls().length);
- }
-
- @Test
- public void testNoParameters() {
- Response mockedResponse = mockClientResponse("/noParamQuery.rdf");
-
- OslcQuery query = new OslcQuery(new OslcClient(), "http://example.com/provider/query");
- OslcQueryResult result = new OslcQueryResult(query, mockedResponse);
- assertEquals(2, result.getMembersUrls().length);
- }
-
- @Test
- public void testFolderQuery() {
- Response mockedResponse = mockClientResponse("/queryFolderResponse.rdf");
-
- OslcQueryParameters params = new OslcQueryParameters();
- params.setPrefix("dcterms=,nav=");
- params.setSelect("*");
-
- OslcQuery query = new OslcQuery(new OslcClient(), "https://192.168.99.3:9443/rm/folders", params);
- OslcQueryResult result = new OslcQueryResult(query, mockedResponse);
- assertEquals(1, result.getMembersUrls().length);
- }
-
- @Test
- public void testQuery() {
- Response mockedResponse = mockClientResponse("/queryResponse.rdf");
-
- OslcQueryParameters params = new OslcQueryParameters();
- params.setWhere("ex:product=\"Product A\"");
- OslcQuery query = new OslcQuery(new OslcClient(), "http://example.com/provider/query", params);
- OslcQueryResult result = new OslcQueryResult(query, mockedResponse);
- assertEquals(2, result.getMembersUrls().length);
- }
-
- @Test
- public void testBlogQuery() {
- Response mockedResponse = mockClientResponse("/blogQuery.rdf");
-
- OslcQueryParameters params = new OslcQueryParameters();
- params.setSelect("dcterms:title");
- OslcQuery query = new OslcQuery(new OslcClient(), "http://example.com/query");
- OslcQueryResult result = new OslcQueryResult(query, mockedResponse);
- result.setMemberProperty("http://open-services.net/ns/bogus/blogs#comment");
- assertEquals(5, result.getMembersUrls().length);
- }
-
- @Test
- public void testAnyMember() {
- System.setProperty(OslcQueryResult.SELECT_ANY_MEMBER, "true");
- Response mockedResponse = mockClientResponse("/blogQuery.rdf");
-
- OslcQueryParameters params = new OslcQueryParameters();
- params.setSelect("dcterms:title");
- OslcQuery query = new OslcQuery(new OslcClient(), "http://example.com/query");
- OslcQueryResult result = new OslcQueryResult(query, mockedResponse);
- assertEquals(5, result.getMembersUrls().length);
- }
-
- private Response mockClientResponse(String file) {
- final InputStream is = OslcQueryResultTest.class.getResourceAsStream(file);
- Response mockedResponse = Mockito.mock(Response.class);
- when(mockedResponse.readEntity(InputStream.class)).thenReturn(is);
-
- return mockedResponse;
- }
-
-}
diff --git a/client/oslc-client/src/test/java/org/eclipse/lyo/client/query/OslcQueryResultTest.java b/client/oslc-client/src/test/java/org/eclipse/lyo/client/query/OslcQueryResultTest.java
new file mode 100644
index 000000000..126069d24
--- /dev/null
+++ b/client/oslc-client/src/test/java/org/eclipse/lyo/client/query/OslcQueryResultTest.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2020 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License 1.0
+ * which is available at http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+package org.eclipse.lyo.client.query;
+
+import jakarta.ws.rs.core.Response;
+import org.eclipse.lyo.client.OslcClient;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.io.InputStream;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+/**
+ * @author Samuel Padgett
+ */
+public class OslcQueryResultTest {
+ @Before
+ public void clearPublicURISystemProperty() {
+ System.clearProperty(OslcQueryResult.SELECT_ANY_MEMBER);
+ }
+
+ @Test
+ public void testEmpty() {
+ Response mockedResponse = mockClientResponse("/emptyQuery.rdf");
+
+ OslcQueryParameters params = new OslcQueryParameters();
+ params.setWhere("dceterms:identifier=3");
+ OslcQuery query = new OslcQuery(new OslcClient(), "http://example.com/provider/query",
+ params);
+ OslcQueryResult result = new OslcQueryResult(query, mockedResponse);
+ assertEquals(0, result.getMembersUrls().length);
+ }
+
+ @Test
+ public void testNoParameters() {
+ Response mockedResponse = mockClientResponse("/noParamQuery.rdf");
+
+ OslcQuery query = new OslcQuery(new OslcClient(), "http://example.com/provider/query");
+ OslcQueryResult result = new OslcQueryResult(query, mockedResponse);
+ assertEquals(2, result.getMembersUrls().length);
+ }
+
+ @Test
+ public void testFolderQuery() {
+ Response mockedResponse = mockClientResponse("/queryFolderResponse.rdf");
+
+ OslcQueryParameters params = new OslcQueryParameters();
+ params.setPrefix("dcterms=,nav=");
+ params.setSelect("*");
+
+ OslcQuery query = new OslcQuery(new OslcClient(), "https://192.168.99.3:9443/rm/folders",
+ params);
+ OslcQueryResult result = new OslcQueryResult(query, mockedResponse);
+ assertEquals(1, result.getMembersUrls().length);
+ }
+
+ @Test
+ public void testQuery() {
+ Response mockedResponse = mockClientResponse("/queryResponse.rdf");
+
+ OslcQueryParameters params = new OslcQueryParameters();
+ params.setWhere("ex:product=\"Product A\"");
+ OslcQuery query = new OslcQuery(new OslcClient(), "http://example.com/provider/query",
+ params);
+ OslcQueryResult result = new OslcQueryResult(query, mockedResponse);
+ assertEquals(2, result.getMembersUrls().length);
+ }
+
+ @Test
+ public void testBlogQuery() {
+ Response mockedResponse = mockClientResponse("/blogQuery.rdf");
+
+ OslcQueryParameters params = new OslcQueryParameters();
+ params.setSelect("dcterms:title");
+ OslcQuery query = new OslcQuery(new OslcClient(), "http://example.com/query");
+ OslcQueryResult result = new OslcQueryResult(query, mockedResponse);
+ result.setMemberProperty("http://open-services.net/ns/bogus/blogs#comment");
+ assertEquals(5, result.getMembersUrls().length);
+ }
+
+ @Test
+ public void testAnyMember() {
+ System.setProperty(OslcQueryResult.SELECT_ANY_MEMBER, "true");
+ Response mockedResponse = mockClientResponse("/blogQuery.rdf");
+
+ OslcQueryParameters params = new OslcQueryParameters();
+ params.setSelect("dcterms:title");
+ OslcQuery query = new OslcQuery(new OslcClient(), "http://example.com/query");
+ OslcQueryResult result = new OslcQueryResult(query, mockedResponse);
+ assertEquals(5, result.getMembersUrls().length);
+ }
+
+ @Test
+ public void testMultiResponseInfos() {
+ // seems to work with both
+// System.setProperty(OslcQueryResult.SELECT_ANY_MEMBER, "false");
+ Response mockedResponse = mockClientResponse("/multiResponseQuery.rdf");
+
+ OslcQueryParameters params = new OslcQueryParameters();
+ params.setSelect("dcterms:title");
+ OslcQuery query = new OslcQuery(new OslcClient(), "https://nordic.clm.ibmcloud" +
+ ".com/ccm/oslc/contexts/_2nC4UBNvEeutmoeSPr3-Ag/workitems");
+ OslcQueryResult result = new OslcQueryResult(query, mockedResponse);
+ assertEquals(20, result.getMembersUrls().length);
+ }
+
+ private Response mockClientResponse(String file) {
+ final InputStream is = OslcQueryResultTest.class.getResourceAsStream(file);
+ Response mockedResponse = Mockito.mock(Response.class);
+ when(mockedResponse.readEntity(InputStream.class)).thenReturn(is);
+
+ return mockedResponse;
+ }
+
+}
diff --git a/client/oslc-client/src/test/resources/multiResponseQuery.rdf b/client/oslc-client/src/test/resources/multiResponseQuery.rdf
new file mode 100644
index 000000000..28de9614d
--- /dev/null
+++ b/client/oslc-client/src/test/resources/multiResponseQuery.rdf
@@ -0,0 +1,1397 @@
+
+
+
+
+
+
+ 126285: Program
+
+
+
+
+
+
+ DP-479
+
+
+ 2021-09-16T18:32:37.865Z
+
+
+ 2021-09-16T18:32:38.238Z
+
+
+ Image elements must provide a description in the 'alt' attribute for consumption by screen readers.
+
+
+ false
+ 1535
+
+
+ false
+
+ 1535
+
+
+
+ false
+
+
+
+
+ Implement accessibility in Pet Store application (updated)
+ _2nC4UBNvEeutmoeSPr3-Ag
+
+
+
+
+ false
+ false
+ false
+
+ false
+ false
+
+
+ Task
+ New
+
+ Task 1535
+
+
+
+
+ Defect
+ false
+
+
+ 1115
+
+
+ false
+
+
+
+ 2021-04-07T10:38:21.136Z
+
+ _2nC4UBNvEeutmoeSPr3-Ag
+ 2021-04-07T10:38:21.155Z
+ This is a System Change Request (A Defect)
+
+
+
+
+ false
+ New
+ Defect 1115
+
+
+
+
+
+
+
+
+
+ false
+ 1115
+
+
+ false
+ false
+ false
+ false
+
+
+
+
+
+
+
+
+ 1044: PI Objective (Team)
+
+
+ Subscribed By
+ 1
+
+
+
+
+
+
+
+ DP-471
+
+
+
+
+
+
+
+
+ Story
+ false
+
+ false
+ 2020-10-21T09:38:25.551Z
+
+
+ false
+ 1046
+ New
+ 2020-10-21T10:00:12.918Z
+
+ Story
+
+ Story 1046
+
+ false
+
+
+ false
+
+
+
+
+
+ false
+
+ 1046
+
+ false
+ false
+
+ false
+
+ 0
+
+
+
+
+
+
+ _2nC4UBNvEeutmoeSPr3-Ag
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Accessibility verification using a screen reader
+
+
+ 2021-09-16T18:26:47.443Z
+
+
+
+
+
+
+
+ false
+ false
+
+ Image elements must provide a description in the 'alt' attribute for consumption by screen readers.
+ false
+ _2nC4UBNvEeutmoeSPr3-Ag
+
+
+ false
+
+
+
+ 1531
+
+ 1531
+ false
+
+ New
+
+
+
+
+ Task
+ Task 1531
+ false
+ 2021-09-16T18:26:48.129Z
+
+ Implement accessibility in Pet Store application (updated)
+ false
+
+ false
+
+
+
+
+
+
+
+
+ PI Objective (Program)
+ New
+
+
+ false
+
+
+ PI Objective 1042
+ false
+
+
+
+
+
+
+ false
+
+
+ false
+
+
+
+
+
+ PI Objective
+
+ 2020-10-21T09:39:42.663Z
+ false
+
+ 0
+
+ false
+
+ 1042
+ 1042
+
+
+ _2nC4UBNvEeutmoeSPr3-Ag
+
+
+
+ false
+ false
+
+ 2020-10-21T09:32:48.097Z
+
+
+
+
+
+
+
+
+ Story 1050
+ 1050
+ false
+ 2020-12-14T11:45:52.188Z
+
+
+
+
+
+ false
+
+
+ false
+
+
+ false
+
+
+
+ 0
+ 2020-12-14T11:53:03.066Z
+ _2nC4UBNvEeutmoeSPr3-Ag
+
+ New
+
+
+
+
+
+
+
+ Story
+
+
+ false
+
+ false
+
+ false
+
+
+ false
+ 1050
+
+ false
+
+
+ This is my story
+
+
+
+
+
+
+ configuring Essential SAFe for additional post-project initialization instructions
+
+
+
+
+
+
+ 1044: PI Objective (Team)
+
+
+
+
+
+
+ Accessibility verification using a screen reader
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Subscribed By
+ 1
+
+
+
+
+
+
+
+ Accessibility verification using a screen reader
+
+
+ Subscribed By
+ 1
+
+
+
+ Subscribed By
+ 1
+
+
+
+ Defect
+ 2021-09-16T18:32:39.076Z
+
+ Defect 1536
+
+
+
+
+
+ false
+ false
+
+
+
+
+ false
+
+ false
+
+ false
+
+
+ _2nC4UBNvEeutmoeSPr3-Ag
+
+
+ New
+ Error logging in
+
+ 1536
+
+ 1536
+
+
+ false
+ An error occurred when I tried to log in with a user ID that contained the '@' symbol.
+
+ false
+
+
+
+
+
+ 2021-09-16T18:32:39.067Z
+ false
+
+
+
+
+
+
+ DP-528
+
+
+
+
+
+
+ DP-457
+
+
+ 2021-04-08T13:11:56.081Z
+ false
+
+
+
+
+
+
+
+ _2nC4UBNvEeutmoeSPr3-Ag
+
+
+ Task
+
+
+
+ false
+ 1116
+
+ 1116
+ New
+
+
+
+
+
+ false
+ false
+ false
+ false
+
+
+
+
+
+ 2021-04-07T10:40:39.882Z
+
+ Task 1116
+ false
+ false
+
+
+ need to create a ChangeRequest from Polarion
+
+
+
+
+ false
+
+
+ false
+ false
+ Defect 1532
+
+
+
+
+
+
+
+
+ _2nC4UBNvEeutmoeSPr3-Ag
+ New
+ false
+
+
+ Defect
+
+
+
+ 1532
+
+ 2021-09-16T18:26:49.032Z
+ false
+
+
+ Error logging in
+ false
+
+
+
+ false
+
+ 2021-09-16T18:26:49.021Z
+ false
+ An error occurred when I tried to log in with a user ID that contained the '@' symbol.
+
+
+ 1532
+
+
+
+
+
+
+
+ 126288: Non-Functional Requirement
+
+
+
+
+
+
+ DP-471
+
+
+ false
+ false
+
+ false
+
+
+
+
+ 2020-10-21T09:41:53.360Z
+ For <customers> who <do something> the <solution> is a <something - the "how"> that <provides this value> Unlike <competitor, current solution, or non-existing solution> our solution <does something better - the "why">
Outcomes hypothesis:
*
*
Leading indicators:
* (early innovation accounting measures)
*
NFRs:
*
*
+ _2nC4UBNvEeutmoeSPr3-Ag
+
+
+
+
+
+ 1047
+
+
+
+
+ 2020-10-21T09:41:27.851Z
+
+ Draft
+ false
+ 1047
+ 0
+
+
+ 0
+ Program Epic 1047
+
+ 0
+
+
+
+
+
+ Program Epic
+ false
+
+
+
+
+ false
+ 0.0
+ false
+ Program Epic
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+ 1045: Feature
+
+
+
+
+
+
+ Global Verifcation Test
+
+
+ Subscribed By
+ 1
+
+
+
+ false
+ false
+
+
+ false
+
+ 1051
+ Task 1051
+
+
+ New
+ Test task demo for Erik
+ false
+
+ 2021-04-07T10:55:47.342Z
+
+ false
+
+ Task
+
+ _2nC4UBNvEeutmoeSPr3-Ag
+
+
+
+
+ false
+
+
+
+
+ false
+ 1051
+
+
+ 2021-01-22T15:14:53.538Z
+
+
+
+
+
+
+ false
+
+
+
+
+ Subscribed By
+ 1
+
+
+
+
+
+
+
+ Accessibility verification using a screen reader
+
+
+ Subscribed By
+ 1
+
+
+
+ Subscribed By
+ 1
+
+
+
+
+
+
+
+ Global Verifcation Test
+
+
+
+
+
+
+ 126286: Team Non-Functional Requirement
+
+
+
+
+
+
+ DP-529
+
+
+
+ Implement accessibility in Pet Store application (updated)
+ 2310
+
+ false
+ false
+
+
+ false
+
+ false
+
+
+ Task
+
+
+ false
+
+
+ Task 2310
+
+ false
+
+ 2310
+ 2023-07-16T19:19:27.418Z
+ _2nC4UBNvEeutmoeSPr3-Ag
+
+ false
+
+
+
+
+ false
+ New
+
+ 2023-07-16T19:19:26.374Z
+
+
+
+ Image elements must provide a description in the 'alt' attribute for consumption by screen readers.
+
+
+
+
+
+
+
+
+
+ 1046: Story
+
+
+
+
+
+ false
+
+
+ 1537
+
+
+
+ false
+
+
+ 1537
+
+ false
+ false
+
+ 2021-09-16T18:32:56.025Z
+ Image elements must provide a description in the 'alt' attribute for consumption by screen readers.
+
+ Task
+
+
+
+ 2021-09-16T18:32:55.653Z
+
+
+ false
+ false
+
+ Task 1537
+ false
+
+
+ Implement accessibility in Pet Store application (updated)
+ _2nC4UBNvEeutmoeSPr3-Ag
+
+
+ New
+
+
+ false
+
+
+
+
+ Task
+ 1533
+
+ _2nC4UBNvEeutmoeSPr3-Ag
+ New
+ Implement accessibility in Pet Store application (updated)
+
+ false
+ Task 1533
+ false
+
+
+
+ 2021-09-16T18:31:15.255Z
+
+ 1533
+
+
+
+
+ false
+
+
+
+
+ false
+ false
+
+ false
+ false
+
+ Image elements must provide a description in the 'alt' attribute for consumption by screen readers.
+
+
+ false
+ 2021-09-16T18:31:15.641Z
+
+
+
+
+
+
+
+ Subscribed By
+ 1
+
+
+
+
+
+
+
+ 1042: PI Objective (Program)
+
+
+
+
+
+
+ DP-477
+
+
+ Subscribed By
+ 1
+
+
+
+ Subscribed By
+ 1
+
+
+
+ Subscribed By
+ 1
+
+
+
+
+
+
+
+ DP-527
+
+
+
+
+ false
+
+
+
+ false
+ 1044
+
+
+
+
+
+
+ PI Objective 1044
+ false
+ 1044
+
+
+ false
+
+
+
+ New
+ false
+
+
+
+
+ PI Objective (Team)
+
+ false
+ false
+
+ PI Objective
+ false
+
+ 0
+
+
+
+ 2020-10-21T09:40:03.820Z
+ 2020-10-21T09:33:26.547Z
+ _2nC4UBNvEeutmoeSPr3-Ag
+
+
+
+
+
+ Subscribed By
+ 1
+
+
+
+
+ Work Items
+ 537
+
+
+
+ Subscribed By
+ 1
+
+
+
+
+
+ _2nC4UBNvEeutmoeSPr3-Ag
+
+
+ false
+
+ false
+
+
+
+ 1040
+
+ Post-Project Initialization
+
+ false
+
+
+ 2020-10-21T07:35:20.513Z
+
+ New
+ false
+
+
+ 2020-10-21T07:35:20.370Z
+ Task 1040
+
+ See, configuring Essential SAFe for additional post-project initialization instructions.
+ false
+
+ false
+ Task
+
+
+
+ false
+ false
+
+
+
+ 1040
+
+
+
+
+ Subscribed By
+ 1
+
+
+
+
+
+
+
+ 1045: Feature
+
+
+
+
+
+
+ 126287: Team User Requirement
+
+
+
+
+
+
+ Accessibility verification using a screen reader
+
+
+
+
+ false
+
+
+
+
+ false
+ 2021-04-08T13:14:06.622Z
+ 1118
+
+
+ 1118
+
+
+ Feature 1118
+
+ false
+
+
+ 0
+ 0.0
+ Draft
+ false
+
+
+
+
+ false
+
+
+ 0
+ false
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+ 2021-11-08T08:35:53.632Z
+
+
+ A Change Request to trace to many development tasks in Polarion
+ 0
+
+
+
+
+
+
+ false
+
+ Feature
+
+ _2nC4UBNvEeutmoeSPr3-Ag
+ false
+
+
+
+
+
+
+
+ DP-525
+
+
+
+ Defect 1538
+
+ false
+ false
+
+
+ false
+ 1538
+
+ false
+ _2nC4UBNvEeutmoeSPr3-Ag
+
+
+ New
+
+
+
+
+ false
+
+
+ false
+
+
+
+ false
+ An error occurred when I tried to log in with a user ID that contained the '@' symbol.
+
+ 1538
+
+
+
+
+
+ false
+ Defect
+
+ 2021-09-16T18:32:56.877Z
+ Error logging in
+ 2021-09-16T18:32:56.868Z
+
+
+
+
+
+ Subscribed By
+ 1
+
+
+
+
+
+
+
+ 126289: User Requirement
+
+
+
+
+
+
+ DP-479
+
+
+ false
+ false
+
+
+
+
+ 1534
+
+
+ Error logging in
+ _2nC4UBNvEeutmoeSPr3-Ag
+
+ New
+
+ false
+ Defect
+ false
+
+ 2021-09-16T18:31:16.492Z
+
+
+
+
+
+
+ false
+ 2021-09-16T18:31:16.501Z
+
+
+
+ Defect 1534
+
+ false
+ 1534
+
+
+
+
+
+
+ An error occurred when I tried to log in with a user ID that contained the '@' symbol.
+ false
+
+ false
+
+
+
+
+
+
+ 1046: Story
+
+
+ Subscribed By
+ 1
+
+
+
+
+
+
+
+ DP-440
+
+
+
+
+
+
+ false
+
+
+
+
+ 1045
+
+
+
+
+
+
+
+
+ _2nC4UBNvEeutmoeSPr3-Ag
+ false
+
+
+
+
+
+ false
+
+ false
+ false
+
+ 2020-10-21T09:37:00.992Z
+
+ false
+
+
+ 1045
+ 2020-12-11T15:19:32.749Z
+ Draft
+
+
+
+ Feature
+ 0.0
+ 0
+
+ Feature
+
+
+
+ 0
+
+
+
+ Feature 1045
+ 0
+
+ false
+
+
+
+
+
+
+
+ false
+ false
+
+
+
+
+
+
+ Global Verifcation Test
+
+
+ Subscribed By
+ 1
+
+
+
+
+
+
+
+ 1045: Feature
+
+
+
+
+
+
+ Global Verifcation Test
+
+
+
+
+
+
+ 1047: Program Epic
+
+
+ Subscribed By
+ 1
+
+
+
+
+
+
+
+ 1042: PI Objective (Program)
+
+
+ Subscribed By
+ 1
+
+
+
+
+
+
+
+ DP-528
+
+
diff --git a/client/oslc-client/src/test/resources/simplelogger.properties b/client/oslc-client/src/test/resources/simplelogger.properties
new file mode 100644
index 000000000..9eb12ca52
--- /dev/null
+++ b/client/oslc-client/src/test/resources/simplelogger.properties
@@ -0,0 +1,2 @@
+org.slf4j.simpleLogger.defaultLogLevel=info
+org.slf4j.simpleLogger.log.org.eclipse.lyo=trace