Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
* Copyright 2015-2016 ForgeRock AS
* Portions Copyright 2011 Viliam Repan
* Portions Copyright 2011 Radovan Semancik
* Portions Copyright 2026 3A Systems, LLC.
*/
package org.forgerock.openicf.csvfile;

Expand Down Expand Up @@ -881,6 +882,9 @@ private ConnectorObject findObjectInFile(File file, Uid uid) {
}

private SyncDelta generateSyncDelta(ConnectorObject origin, ConnectorObject current, SyncToken token) {
if (origin == null && current == null) {
throw new IllegalArgumentException("Either the original or the current object is required");
}
SyncDeltaBuilder builder = new SyncDeltaBuilder();
builder.setUid(origin == null ? current.getUid() : origin.getUid());
builder.setToken(token);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ public Uid update(ObjectClass oclass, Uid uid, Set<Attribute> attrs, OperationOp
log.info("Append empty attribute {0} for required columnName {1}", attributeName, columnName);
value = DatabaseTableConstants.EMPTY_STR;
}
final Integer sqlType = getColumnType(columnName);
final int sqlType = getColumnType(columnName);
final SQLParam param = new SQLParam(quoteName(columnName), value, sqlType);
updateSet.addBind(param);
log.ok("Appended to update statement the attribute {0} for columnName {1} and sqlType {2}", attributeName, columnName, sqlType);
Expand Down Expand Up @@ -609,7 +609,7 @@ public void sync(ObjectClass oclass, SyncToken token, SyncResultsHandler handler
if(token != null && token.getValue() != null) {
final Object tokenVal = token.getValue();
log.info("Sync token is {0}", tokenVal);
final Integer sqlType = getColumnType(config.getChangeLogColumn());
final int sqlType = getColumnType(config.getChangeLogColumn());
where.addBind(new SQLParam(changeLogColumnName, tokenVal, sqlType),">" );
}
final DatabaseQueryBuilder query = new DatabaseQueryBuilder(tblname, columnNames);
Expand Down Expand Up @@ -1082,7 +1082,7 @@ private Set<AttributeInfo> buildAttributeInfoSet(ResultSet rset) throws SQLExcep
for (int i = 1; i <= count; i++) {
final String name = meta.getColumnName(i);
final AttributeInfoBuilder attrBld = new AttributeInfoBuilder();
final Integer columnType = meta.getColumnType(i);
final int columnType = meta.getColumnType(i);
log.ok("column name {0} has type {1}", name, columnType);
columnSQLTypes.put(name, columnType);
if (name.equalsIgnoreCase(config.getKeyColumn())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public DatabaseTableFilterTranslator(DatabaseTableConnector connector, ObjectCla
protected SQLParam getSQLParam(Attribute attribute, ObjectClass oclass, OperationOptions options) {
final Object value = AttributeUtil.getSingleValue(attribute);
final String columnName = connector.getColumnName(attribute.getName());
final Integer columnType = connector.getColumnType(columnName);
final int columnType = connector.getColumnType(columnName);
return new SQLParam(columnName, value,columnType);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ private static String resolveValue(String value, Properties properties,
int index = 0;
int length = value.length();
StringBuffer result = new StringBuffer();
while (index >= 0 && index < length) {
while (index < length) {
int varStart = value.indexOf("${", index);
if (varStart >= 0) {
int varEnd = value.indexOf('}', varStart);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
* ====================
* Portions Copyrighted 2026 3A Systems, LLC
*/
package org.identityconnectors.dbcommon;

import java.util.Objects;
import java.sql.Types;

/**
Expand Down Expand Up @@ -109,8 +111,7 @@ public boolean equals(Object obj) {
return false;
}
SQLParam other = (SQLParam) obj;
return (name == other.name || (name != null && name.equals(other.name)))
&& (value == other.value || (value != null && value.equals(other.value)))
return Objects.equals(name, other.name) && Objects.equals(value, other.value)
&& sqlType == other.sqlType;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
import org.forgerock.json.resource.CreateRequest;
import org.forgerock.json.resource.DeleteRequest;
import org.forgerock.json.resource.InternalServerErrorException;
import org.forgerock.json.resource.NotSupportedException;
import org.forgerock.json.resource.PatchOperation;
import org.forgerock.json.resource.PatchRequest;
import org.forgerock.json.resource.QueryRequest;
Expand Down Expand Up @@ -492,6 +493,8 @@ private HttpUriRequest convert(Request request) throws ResourceException {
rq = new HttpGet(builder.build());
break;
}
default:
throw new NotSupportedException("Unsupported request type: " + request.getRequestType());
}
} catch (URISyntaxException e) {
throw new InternalServerErrorException(e);
Expand Down Expand Up @@ -708,7 +711,7 @@ public HttpResponseResourceException(ResourceException wrapped) {
}

@Override
public ResourceException getCause() {
public synchronized ResourceException getCause() {
return cause;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -782,24 +782,25 @@ protected Log getLogger(final Class<?> clazz) {

private GroovyScriptEngine groovyScriptEngine = null;

protected GroovyScriptEngine getGroovyScriptEngine() {
/**
* Synchronised for the whole initialisation, not double-checked: the
* customizer script runs against the half-initialised engine (it may call
* back into this configuration, which re-enters here), so other threads
* have to wait until it has run rather than see the engine early.
*/
protected synchronized GroovyScriptEngine getGroovyScriptEngine() {
if (null == groovyScriptEngine) {
synchronized (this) {
if (null == groovyScriptEngine) {

final CompilerConfiguration compilerConfiguration =
new CompilerConfiguration(config);
compilerConfiguration.addCompilationCustomizers(getImportCustomizer(null));
final CompilerConfiguration compilerConfiguration =
new CompilerConfiguration(config);
compilerConfiguration.addCompilationCustomizers(getImportCustomizer(null));

final GroovyClassLoader loader =
new GroovyClassLoader(getParentLoader(), compilerConfiguration, true);
final GroovyClassLoader loader =
new GroovyClassLoader(getParentLoader(), compilerConfiguration, true);

groovyScriptEngine =
new GroovyScriptEngine(getRoots(compilerConfiguration, loader), loader);
groovyScriptEngine =
new GroovyScriptEngine(getRoots(compilerConfiguration, loader), loader);

initializeCustomizer();
}
}
initializeCustomizer();
}
return groovyScriptEngine;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* The contents of this file are subject to the terms of the Common Development and
* Distribution License (the License). You may not use this file except in compliance with the
* License.
*
* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
* specific language governing permission and limitations under the License.
*
* When distributing Covered Software, include this CDDL Header Notice in each file and include
* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
* Header, with the fields enclosed by brackets [] replaced by your own identifying
* information: "Portions copyright [year] [name of copyright owner]".
*
* Copyright 2026 3A Systems, LLC.
*/
package org.forgerock.openicf.misc.crest;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
import java.util.concurrent.Future;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.nio.protocol.HttpAsyncResponseConsumer;
import org.forgerock.json.JsonValue;
import org.forgerock.json.resource.NotSupportedException;
import org.forgerock.json.resource.QueryResourceHandler;
import org.forgerock.json.resource.QueryResponse;
import org.forgerock.json.resource.ReadRequest;
import org.forgerock.json.resource.RequestType;
import org.forgerock.json.resource.Requests;
import org.forgerock.json.resource.ResourceException;
import org.forgerock.json.resource.ResourcePath;
import org.forgerock.services.context.Context;
import org.forgerock.services.context.RootContext;
import org.testng.Assert;
import org.testng.annotations.Test;

public class AbstractRemoteConnectionTest {

private static final class StubConnection extends AbstractRemoteConnection {

StubConnection() {
super(ResourcePath.valueOf("api"), new HttpHost("localhost", 8080));
}

@Override
public boolean isClosed() {
return false;
}

@Override
public <T> Future<T> execute(Context context, HttpUriRequest request,
HttpAsyncResponseConsumer<T> responseConsumer, FutureCallback<T> callback) {
throw new AssertionError("no HTTP request expected, got " + request);
}

@Override
protected JsonValue parseJsonBody(HttpEntity entity, boolean allowEmpty) {
throw new AssertionError();
}

@Override
protected QueryResponse parseQueryResponse(HttpResponse response,
QueryResourceHandler handler) {
throw new AssertionError();
}
}

/** A read request that reports a type no {@code Connection} method produces. */
private static ReadRequest apiTypedRequest() {
final ReadRequest real = Requests.newReadRequest("users/1");
return (ReadRequest) Proxy.newProxyInstance(ReadRequest.class.getClassLoader(),
new Class<?>[] { ReadRequest.class }, (proxy, method, args) -> {
if ("getRequestType".equals(method.getName())) {
return RequestType.API;
}
try {
return method.invoke(real, args);
} catch (InvocationTargetException e) {
throw e.getCause();
}
});
}

@Test
public void testUnsupportedRequestTypeFailsThePromise() throws InterruptedException {
try {
new StubConnection().readAsync(new RootContext(), apiTypedRequest()).getOrThrow();
Assert.fail("NotSupportedException expected");
} catch (ResourceException e) {
Assert.assertTrue(e instanceof NotSupportedException, String.valueOf(e));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* ====================
*
* Portions Copyrighted 2012 ForgeRock AS
* Portions Copyrighted 2026 3A Systems, LLC
*
*/
package org.identityconnectors.contract.test;
Expand All @@ -32,6 +33,7 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -102,7 +104,7 @@ protected void testRun(ObjectClass objectClass) {
List<Set<Attribute>> attrs = new ArrayList<Set<Attribute>>();

// objects stored in connector resource before test
Map<Uid, ConnectorObject> coBeforeTest = null;
Map<Uid, ConnectorObject> coBeforeTest = Collections.emptyMap();

// sync variables
SyncToken token = null;
Expand Down Expand Up @@ -792,7 +794,7 @@ private ObjectClassInfo findOInfo(ObjectClass oclass) {
*/
private static boolean canLockOut() {
// by default it's supposed that case insensitive search is disabled.
Boolean canLockout = true;
boolean canLockout = true;
try {
canLockout = !(Boolean) getDataProvider().getTestSuiteAttribute(
SKIP + "." + LOCKOUT_PREFIX,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,10 @@ public boolean isObjectClassSupported(ObjectClass objectClass) {
oinfos = tmp;
}
}
if (oinfos == null) {
// no operation required: every object class of the schema qualifies
oinfos = getSchema().getObjectClassInfo();
}

// Find the objectclass in set of supported objectclasses (oinfos),
// that is currently tested. If it is present set the indicator _ocSupported accordingly.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* ====================
*
* Portions Copyrighted 2012 ForgeRock AS
* Portions Copyrighted 2026 3A Systems, LLC
*
*/
package org.identityconnectors.contract.test;
Expand Down Expand Up @@ -416,7 +417,7 @@ static String changeCase(String str_uid) {
*/
protected static boolean canSearchCaseInsensitive() {
// by default it's supposed that case insensitive search is disabled.
Boolean canSearchCIns = true;
boolean canSearchCIns = true;
try {
canSearchCIns = !(Boolean) getDataProvider().getTestSuiteAttribute(
DISABLE + "." + CASE_INSENSITIVE_PREFIX,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
* ====================
*
* Portions Copyrighted 2012 ForgeRock AS
* Portions Copyrighted 2026 3A Systems, LLC
*
*/
package org.identityconnectors.contract.test;
Expand Down Expand Up @@ -314,7 +315,7 @@ public String getTestName() {
*/
protected static boolean canSyncAfterOp(Class<? extends APIOperation> operation) {
// by default it's supposed that sync works for all change types
Boolean canSync = true;
boolean canSync = true;
try {
if (operation.equals(CreateApiOp.class)) {
canSync = !(Boolean) getDataProvider().getTestSuiteAttribute(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,15 +247,13 @@ public ObjectPoolEntry<T> borrowObject() {
try {
handler.testObject(rv.getPooledObject());
} catch (Exception e) {
if (null != rv) {
dispose(rv);
// if it's a new object, break out of the loop
// immediately
if (rv.isNew()) {
throw ConnectorException.wrap(e);
}
rv = null;
dispose(rv);
// if it's a new object, break out of the loop
// immediately
if (rv.isNew()) {
throw ConnectorException.wrap(e);
}
rv = null;
}
} while (null == rv);
rv.setActive(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,16 @@ public Configuration getConfiguration() {
if (null == configuration) {
synchronized (this) {
if (null == configuration) {
this.configuration =
// fully set up before it is published to other threads
final Configuration bean =
JavaClassProperties.createBean(apiConfiguration
.getConfigurationProperties(), connectorInfo
.getConnectorConfigurationClass());
if (null != apiConfiguration.getChangeListener()
&& configuration instanceof AbstractConfiguration) {
((AbstractConfiguration) configuration).addChangeCallback(this);
&& bean instanceof AbstractConfiguration) {
((AbstractConfiguration) bean).addChangeCallback(this);
}
this.configuration = bean;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* "Portions Copyrighted [year] [name of copyright owner]"
* ====================
* Portions Copyrighted 2010-2015 ForgeRock AS.
* Portions Copyrighted 2026 3A Systems, LLC
*/
package org.identityconnectors.framework.impl.api.local.operations;

Expand Down Expand Up @@ -68,7 +69,7 @@ public SyncToken sync(final ObjectClass objectClass, final SyncToken token,

final SyncResultsHandler handlerChain = handler;
final AtomicReference<SyncToken> result = new AtomicReference<SyncToken>(null);
final Boolean doAll = ObjectClass.ALL.equals(objectClass);
final boolean doAll = ObjectClass.ALL.equals(objectClass);
// SyncTokenResultsHandler handlerChain =
((SyncOp) getConnector()).sync(objectClass, token, new SyncTokenResultsHandler() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ public boolean is(Class<? extends Throwable> expected) {
*/
@Override
@SuppressWarnings("unchecked")
public RemoteWrappedException getCause() {
public synchronized RemoteWrappedException getCause() {
Object o = exception.get(FIELD_CAUSE);
if (o instanceof Map) {
return new RemoteWrappedException((Map<String, Object>) o);
Expand Down
Loading
Loading