blob: 69b734b3f7862349aa7b3c1c08526546f72ff895 [file] [log] [blame]
Title: 2.4 - Adding entries
NavPrev: 2.3-searching.html
NavPrevText: 2.3 Searching
NavUp: 2-basic-ldap-api-usage.html
NavUpText: 2 - Basic LDAP API usage
NavNext: 2.5-deleting.html
NavNextText: 2.5 - Deleting entries
Notice: Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
.
http://www.apache.org/licenses/LICENSE-2.0
.
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
# 2.4 - Adding entries
Adding entries is one of the base operations a user can do on an **LDAP** server. Nevertheless, it's an operation that implies many checks, and frequently the user receives strange error messages. We will see how to add an entry using the **LDAP API**, and analyze the various error cases that can occur.
## Adding an entry
Here is the simplest way to add an entry into the server, assuming that the entry is correct. In order to add an entry, you must provide the location where the entry is stored (its _Dn_) and the list of its _Attributes_ contained within it.
Here are two examples where the entry is injected using **LDIF**:
:::Java
@Test
public void testAddLdif1() throws Exception
{
connection.add(
new DefaultEntry(
"cn=testadd,ou=system", // The Dn
"ObjectClass: top",
"ObjectClass: person",
"cn: testadd_cn",
"sn: testadd_sn" ) );
assertTrue( connection.exists( "cn=testadd,ou=system" ) );
}
In this basic example, we are adding a new entry, created using some **LDIF** formatted parameters, the first one being the entry's _Dn_.
Note that it is possible to use some variables in the **LDIF** instead of pure text. Here is the same example, resulting to the same entry being added:
:::Java
@Test
public void testAddLdif2() throws Exception
{
String cn = "testadd_cn";
String sn = "testadd_sn";
connection.add(
new DefaultEntry(
"cn=testadd,ou=system", // The Dn
"ObjectClass: top",
"ObjectClass: person",
"cn", cn, // Note : there is no ':' when using a variable
"sn", sn ) );
assertTrue( connection.exists( "cn=testadd,ou=system" ) );
}
Down the line, what is important is that the _add()_ operation is taking a full **[Entry](6.12-entry.html)**.
We can also create the **[Entry](6.12-entry.html)** in a different way, which is shown in the following paragraphs.
## Sending an _AddRequest_
When more control is needed we ask the server to add an entry by sending an **[AddRequest]()**, which allows a **[Control]()** to be included in the request.
Here is an example (note that the control is just injected to demonstrate the feature, it doesn't really do anything special in this example):
:::java
@Test
public void testAddWithControl() throws Exception
{
assertFalse( connection.exists( "cn=testadd,ou=system" ) );
Entry entry = new DefaultEntry(
"cn=testadd,ou=system",
"ObjectClass : top",
"ObjectClass : person",
"cn: testadd_sn",
"sn: testadd_sn" );
AddRequest addRequest = new AddRequestImpl();
addRequest.setEntry( entry );
addRequest.addControl( new ManageDsaITImpl() );
AddResponse response = connection.add( addRequest );
assertNotNull( response );
assertEquals( ResultCodeEnum.SUCCESS, response.getLdapResult().getResultCode() );
assertTrue( connection.exists( "cn=testadd,ou=system" ) );
}
### Asynchronous addition
Sometimes we need to add an entry, but not check the result immediately. It's just a matter of calling the _addAsync()_ method, which returns a _Future_ that can be checked somewhere else in the code:
:::java
@Test
public void testAddAsyncLdif() throws Exception
{
assertFalse( connection.exists( "cn=testAsyncAdd,ou=system" ) );
Entry entry = new DefaultEntry(
"cn=testAsyncAdd,ou=system",
"ObjectClass: top",
"ObjectClass: person",
"cn: testAsyncAdd_cn",
"sn: testAsyncAdd_sn" );
AddRequest addRequest = new AddRequestImpl();
addRequest.setEntry( entry );
AddFuture addFuture = connection.addAsync( addRequest );
// Here, we can do something else before checking that the entry has been added
AddResponse addResponse = addFuture.get( 1000, TimeUnit.MILLISECONDS );
assertNotNull( addResponse );
assertEquals( ResultCodeEnum.SUCCESS, addResponse.getLdapResult().getResultCode() );
assertTrue( connection.exists( "cn=testAsyncAdd,ou=system" ) );
}
## Do, Don't
Successfully adding an entry assumes that the entry was correct, i.e. the attributes and values are compatible with the LDAP schema. There are many things checked by the server. Here is a list of constraints that you should respect in order to get your entry injected:
* The entry must have at least one **Structural** _ObjectClass_
* If the entry has more than one **Structural** _ObjectClass_, then they must be hierarchically related
* The _ObjectClasses_ define the list of allowed **Structural** _AttributeTypes_ that can be used (**MAY** and **MUST**)
* All the **MUST** **[AttributeTypes]()** must be present
* Each added value must follow the _AttributeType_ _Syntax_
* If the _AttributeType_ is single valued, then you can't add more than one value
* The entry's _Dn_ must have a parent
* You are not allowed as a user to inject operational attributes, unless they have the **USER-MODIFICATION** flag set to true.
There are also some other constraints, depending on the server, if it implements _NameForms_, _DITStructureRules_ or _DITContentRules_.
Another reason an entry can be rejected is that there aren't enough privilege to add it. You must ensure the LDAP server's configuration allows you to add an entry in the correct location.
## Errors
<DIV class="note" markdown="1">
At first, you might expect to get an exception if the entry addition has failed. If the server is rejecting the addition, <b>you will get NO exception*</b>. Exceptions are only thrown client side if the entry is not built correctly, or if the connection is not opened.
In any other case, the server will simply return a <b>[LdapResult]()</b> instance containing either <b>SUCCESS</b> or the cause of the rejection.
</DIV>
Usually, if you get an error while adding an entry, the message is hard to read. Most of the errors occur because the entry already exists, or because the entry has an LDAP schema violation.
The _LdapResult_ in the response will provide helpful clues as to what the root cause is.