First mail about the new API ! Can everyone count himlself ?

2009-09-30 Thread Emmanuel Lecharny

Hi all,

just to initialize the archiver ...

Mails from this mailing list might be found on 
http://mail-archives.apache.org/mod_mbox/directory-api (probably)


--
--
cordialement, regards,
Emmanuel Lécharny
www.iktek.com
directory.apache.org




Let's start for real ?

2009-11-24 Thread Emmanuel Lecharny

Hi guys,

what about starting for real to work on this common API ? We have had
many preliminary discussions, and also have done a common presentation
with Ludovic 2 months ago. I was pretty busy since then, but right now,
the urgency to get a clean API is getting higher.

We have already clarified what a common API should be about. I suggest
we start by defining the names we want to use for the base objects.

There are a few which are really genuine to ldap, namely, DN, RDN, AVA,
Entry, Attribute, Modification, Control, LdapURL, AttributeType,
DitContentRule, DitStructureRule, MatchingRule, MatchingRuleUse,
NameForm, ObjectClass, Syntax, ResultCode, OID and CSN.

i'm not sure I have listed all the base objects, so feel free to add
those you think are missing.

Also those names are not the final ones. The idea is to discuss about
the exact names we will use. For instance, DN is not necessarily the
most common form. Many APIs or implementations are using LdapDn or
LdapDN. Assuming that the Java naming convention requires that the first
letter only to be upcased, one can think that Dn or Rdn is a better name.

Please feel free to give your opinion.


DN : I would rather use Dn
RDN : Same her, Rdn sounds better to me
AVA : idem, Ava
Entry : fine
Attribute : fine, except that it collides with JNDI attributes, making
the JNDI -> new API translation cumbersome. EntryAttribute ?
Modification : Fine
Control : Fine
LdapURL : LdapUrl has my preference
AttributeType : Fine
DitContentRule : Fine
DitStructureRule : Fine
MatchingRule : Fine
MatchingRuleUse : Fine
NameForm : Fine
ObjectClass : Fine
Syntax : Fine, or LdapSyntax
ResultCode : Fine
OID: Oid for me
CSN: Csn again, same reason

--
--
cordialement, regards,
Emmanuel Lécharny
www.iktek.com
directory.apache.org





Re: Let's start for real ?

2009-11-27 Thread Emmanuel Lecharny
On Fri, Nov 27, 2009 at 9:56 AM, Ludovic Poitou  wrote:
> Sorry for the delayed answer.
> Matt wasn't subscribed to the list (I think it's done now), and I'm out of 
> the office for a conference.
> We will be back in the office on Monday and will give some answer (unless 
> Matt beats me with it).
> Overall I do think we should try to match the names (and case) used in the 
> RFC.

Sure, as much as possible. This is why we picked LdapDn instead of DN,
and such names. I just have an issue with Attribute, because if we
want to write a wrapper around JNDI, it will end with ugly package
bnames to be added in the code to avoid confusion between Attribute
(jndi) and Attribute (API)...

PS : Does Matt received my mail ? Or should I resubmit it to the list ?

-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com


Re: Let's start for real ?

2009-11-27 Thread Emmanuel Lecharny
On Fri, Nov 27, 2009 at 10:24 AM, Francois  wrote:
> On 27/11/2009 10:05, Emmanuel Lecharny wrote:
>>
>> Sure, as much as possible. This is why we picked LdapDn instead of DN,
>> and such names. I just have an issue with Attribute, because if we
>> want to write a wrapper around JNDI, it will end with ugly package
>> bnames to be added in the code to avoid confusion between Attribute
>> (jndi) and Attribute (API)...
>
> I don't think we should sacrifice the general public API
> cleanness/homogeneity for the specific JNDI wrapper case.
>
> What we should be looking for is to have the best, cleanest LDAP API - in
> the long term, it is the only one that matters.

You are probably right.

> And for the confusion, well I don't think javax.naming.directory.Attribute
> brings much of it :)

It's just that I don't like to see packages in the code...

But it may be just me :)


-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com


Re: Let's start for real ?

2009-11-27 Thread Emmanuel Lecharny
Ok, so we can start with :

DN
RDN
AVA
Entry
Attribute
Modification
Control
AttributeType
DitContentRule
DitStructureRule
MatchingRule
MatchingRuleUse
NameForm
ObjectClass
Syntax
ResultCode

Still to be decided :
LdapURL or LdapUrl ? I'm fine with both, but I don't like LDAPURL

OID: It's much more a ASN.1 notion, right. But in many case, we may
manipulate an OID instead of a String. Frankly, the only thing I do
with such a class right now is to use a static method named OID.isOid(
String ). It can be left outside of the API too.

CSN: Or EntryCSN. Not sure that it should be exposed too.

> A data type that we have found particularly useful is AttributeDescription


If this is a wrapper on top of an AttributeType (or an ID), with
options, then it sounds like a good idea. It could help having a
lightweight API instead of having tens of methods for each specific
case : AT with options, etc.


> We don't require that the client API has a schema available. The default
> schema can be either the built in standard "core" schema (e.g. cn, sn, etc)
> or it could even be the built in "empty" schema, both of which fake up
> missing attribute type definitions on demand (in which case they use octet
> string syntax and equality matching). This is nice because it means that the
> API does not need get bloated by having two API abstractions (non schema
> aware and  schema aware).

We discussed a lot with Ludo about it. The Client API must not be
schema aware, but it must allow someone to use a schema if needed. The
default would be to use the core schema.

In order to use the Schema within an entry, it would just be a matter
of injecting the Schema into the Entry, either in the constructor, or
later. It will of course propagate to all the included AT, Dn, etc...
The details have to be explicited, of course


> Here's some other types that you'll probably need:
>
>   * Filter - this is the raw Filter structure defined in RFC 4511
>     protocol def. We also have a Matcher object (in the style of the
>     Regex APIs) which represents a Filter compiled against a
>     particular schema.

Filter, +1

I'm not sure about the Matcher object, as it's supposed to be used by
the server only. But who knows?

>   * Assertion - represents an attribute value assertion compiled by a
>     MatchingRule - typically these are stored in a compiled Filter
>     (Matcher)

Same as above...

>   * Schema - a container of attribute types, object classes, etc

We call it SchemaManager in ADS, Schema is definitively better. +1

>   * ByteString and/or AttributeValue - you'll need at the bear minimum
>     a ByteString for storing attribute values. You may decide that you
>     need an AttributeValue as well in order to cache the normalized
>     form, but I don't think that it's necessary and it just bloats the
>     API and memory - the Attribute can cache normalized forms.
>     Matching rules will need to normalize bytes. For such a low level
>     primitive it's best to use an immutable object for this. We also
>     have a ByteSequence and ByteStringBuilder in the same manner as
>     CharSequence, StringBuilder, and String.

Again, a lot of discussion about it. I'm not convinced that we really
need a ByteString object, as data are either String or byte[], and
String will be internally converted to byte[] (after a PrepareString
normalization). The AttributeValue is what I called AVA (sticking to
the RFC terminology). It makes sense to me to have such an object, as
we have to keep the user provided value, and to have a normalized form
of this value. Of course, you can cach such a value in the Attribute,
but you will have to do the same thing for the RDNs.

I would arther discuss those specific points on another thread to not
confuse people.

>   * Search scope (needs to be extensible - i.e. not an enum)

So Scope or SearchScope ? Also, does it really have to be extensible ?

>   * Modification type (needs to be extensible - i.e. not an enum)

Operation ? ModOp?

>   * Dereference aliases policy

Sure. Don't have a name in mind

>   * Condition result for filters (true, false, undefined)

Yup. A name ?


-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com


Re: Let's start for real ?

2009-11-27 Thread Emmanuel Lecharny
>
> Yes - I'm on the list now - I joined yesterday afternoon. :-)

Welcome ! I hope that Sun LDAP developpers will stay at sun long enouh
to complete this API definition (I just read that Jean-François Arcand
will leave Sun on dec. 4th... What a loss :/ ). Anyways, that's life
...

>
> I agree with Ludo's comment above regarding naming. Something we've been
> trying to do is to follow the RFC naming as much as possible as well as
> following Java naming conventions. Sometimes there is a choice of name to
> use (e.g. LDAPDN from RFC4511 which looks ugly all uppercase, or DN from
> RFC4512 which looks silly in mixed case but good in uppercase). We've chosen
> DN in this case for simply for reasons of familiarity: most people refer to
> distinguish names as DNs - not LDAP DNs.

This is a road I also walk : all the messages definition in ADS are
closely defined following the RFCs, even if it sounds silly sometime
(Object instead of DN, etc...)

I proposed Dn just because it was a mix between something easy to use
(better than LdapDN : whatever, is there any DN outside of the LDAP
world ? ;), and because of the Sun JAVA naming convention. But
considering that it's a composite name (Distinguished Name), DN fits
well too.

Ok, let's stay with DN.
RDN too, I guess.


> I've also been cutting and pasting bits of the RFC text into the Javadoc
> where possible and linking to it, so that people feel "closer" to the
> standard. I think, if possible, we should take a similar approach in this
> joint LDAP SDK effort, assuming that we are allowed to quote bits of RFC
> since they are Copyrighted? Obviously the Javadoc would look pretty ugly if
> we had to put "Copyright (C) The Internet Society" everywhere.

Well, if quoted correctly, this is not an isssue. I guess that a
mention of the copyright in a notice.txt should be fine.



-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com


Re: Let's start for real ?

2009-11-27 Thread Emmanuel Lecharny
On Fri, Nov 27, 2009 at 11:23 AM, Matthew Swift  wrote:
> Hi Emmanuel
>
>> Also those names are not the final ones. The idea is to discuss about
>> the exact names we will use. For instance, DN is not necessarily the
>> most common form. Many APIs or implementations are using LdapDn or
>> LdapDN. Assuming that the Java naming convention requires that the first
>> letter only to be upcased, one can think that Dn or Rdn is a better name.
>>
>
>
> I think that this convention applies to words in Java names, and not
> necessarily abbreviations such as DN. In fact a cursory look through the
> JDK6/J2EE6 APIs will reveal that there is definitely no convention! Take a
> look at javax.xml.* where they seem to mix XML/Xml and HTTP/Http and various
> other well known abbreviations with gay abandon :-)
>
> My personal preference and our convention here has been to use uppercase for
> abbreviations, but I don't feel so strongly to let such a detail get in the
> way of progress.
>
> I think that the most important things to focus on are to make the SDK easy
> to learn and easy to use and that means keeping it small, clean, and
> consistent.

Totally agree. As soon as we have a convenient naming that mostly fits
everyone (religoious war appart), let's move on.

I just have preferences, which may just be bad taste anyways...




-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com


Re: Let's start for real ?

2009-11-27 Thread Emmanuel Lecharny
> Anyway, we can cross this bridge when we come to it. I don't think that it's
> a priority now.

Absolutely.

In fact, to be frank, the reason I mentionned this problem is because
we had a full JNDI layer built into ADS, and we ditched it last year.
The problem was that it was not easy to ditch it cimpletely, as the
external interface was still JNDI, and I had to write the converters,
which was a PITA.

Now, considering what is doing UnboundId, ie a JNDI layer on top of
their API, at some point, we may need to design a SPI based on our
API. But again, everything will be buried in the code, and it's not a
big deal.

So +1 to keep Attribute.


PS : I will create a Wiki page where we will be able to define the API
and comment it, so that we can converge at some point.
-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com


Some naming issue

2009-11-30 Thread Emmanuel Lecharny
Hi,

while reviewing the proposed names, I find Schema a bit problematic
when it comes to cover all the schemaObjects as a whole. Openldap and
ADS can use more than one schema (typically, core, system, ...). At
this point, naming the system in charge of all the schemas something
like 'SchemaHandler' or 'SchemaManager' would be better...

thoughts ?

-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com


WIKI is up and running

2009-11-30 Thread Emmanuel Lecharny
at http://cwiki.apache.org/confluence/display/LDAPAPI/Index

You have to register on Confluence, and ask me for the permissions to
write on the pages. Send me a private e-mail with your user login.

Once logged, the only thing you can do is to view pages and comment
them, unless I grant you write access ! (Spammers, I hate spammers !)

Thanks !

-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com


Re: Some naming issue

2009-11-30 Thread Emmanuel Lecharny
On Mon, Nov 30, 2009 at 3:59 PM, Matthew Swift  wrote:
>
>
> On 30/11/09 11:15, Emmanuel Lecharny wrote:
>>
>> Hi,
>>
>> while reviewing the proposed names, I find Schema a bit problematic
>> when it comes to cover all the schemaObjects as a whole. Openldap and
>> ADS can use more than one schema (typically, core, system, ...). At
>> this point, naming the system in charge of all the schemas something
>> like 'SchemaHandler' or 'SchemaManager' would be better...
>>
>> thoughts ?
>>
>
>
> Our SDK prototype supports multiple schema, each one is an instance of
> "Schema".

So I guess you have a way to manipulate all those supported Schema as
a whole. What's the name for this container ?

Since a Schema is a big heavily used object but relatively static
> we have made the class immutable. In order to create a new Schema we provide
> a SchemaBuilder class with methods like "addAttributeType", etc. Once the
> Schema is built the application converts the builder to a schema instance as
> follows:
>
>   SchemaBuilder builder = new SchemaBuilder();
>   builder.addAttributeType(...);
>   builder.addObjectClass(...);
>   ...
>
>   Schema schema = builder.toSchema();

We handle these operations quite the same, except that the schema is
not immutable per se. However, as the schemas *must* be consistent in
order to be used in the server, we don't allow modifcations that could
break the consistency. What we do (but it's implementation dependent),
is to clone the registries (the container where all the schemaObjects
are loaded), do the modification into this cloned object, chekc the
result, and if it's ok, we apply the same modification to the original
Registries.

Btw, the global container for us is the SchemaManager, which hold what
we call a Registries, itself holding some xxxRegistry (a registry per
SchemaObject). We can inject more than one Schema in the
SchemaManager, and globally enable or disable a schema.


>
> We also provide a version of the toSchema() method which supports storage of
> error messages (e.g. missing elements):
>
>   List messages = new LinkedList();
>   Schema schema = builder.toSchema(messages);
>   for (String message : messages) {
>  // Display errors to user
>   }
>
>
> Why do we need to handle errors like this? Well because schema definitions
> may not be complete and we don't want this to prevent a client from
> proceeding or fixing the broken schema. In particular, RFC4512#4.4 states:
>
>   Clients SHOULD NOT assume that a published subschema is complete,
>   that the server supports all of the schema elements it publishes, or
>   that the server does not support an unpublished element.

Same here, for some othe rreasons : we need to provide Studio a way to
get *all* the errors we have in the Schemas, in order to display all
of them.


> So far in our prototype SDK we haven't needed a SchemaManager. We provide
> access to the singleton Schema objects directly from the Schema class (e.g.
> Schema.getCoreSchema(), Schema.getDefaultSchema(), etc).

Singleton ? Yuk !!! Does not fit at all if you want to embed more than
one instance of the server : typically something one can do when
writing a VD !

It also breaks the RFC : a single server might define more than one
set of Schemas for a specific branch in the tree. (RFC 4512, par. 4.2)

> For other schema (e.g. schema retrieved from a server) we were going to
> provide factory methods in the Connection/AsynchronousConnection interface
> (actually we haven't got these yet - I was going to do them today). Here's
> the idea (we'd have async versions in our AsynchronousConnection interface):

We still have to discuss all those Connection sync/Async aspects...


>   public interface Connection {
>
>  // Common LDAP operations.
>  Result add(AddRequest request) throws ErrorResultException;
>
>  ...
>
>  // Special LDAP operations.
>  Schema getSchemaForEntry(String dn, List errors) throws
>   ErrorResultException;
>
>  Schema getSchemaForEntry(DN dn, List errors) throws
>   ErrorResultException;
>
>  RootDSE getRootDSE() throws ErrorResultException;
>   }
>
>
> This would allow the Connection implementation to manage its schemas. For
> example, implementations may choose to look up schemas on demand and/or
> cache them.

I have to think about it. At first sight, IMO, if an entry has a
subschemaSubentry op attr, then it's not necessary to express the fact
that we want its schema to be loaded : it should be loade d in any
case.


> Something we'd like to support is an "LDIF connection" - a virtual LDAP
> connection to an LDIF file. Basically we 

[Schema awareness] About Schema/SchemaManager(changed the subject)

2009-11-30 Thread Emmanuel Lecharny
On Mon, Nov 30, 2009 at 10:34 PM, Matthew Swift  wrote:
 It also breaks the RFC : a single server might define more than one
>> set of Schemas for a specific branch in the tree. (RFC 4512, par. 4.2)
>>
>>
>
> No - I think that you're misunderstanding me, it's my fault as I'm abusing
> the term singleton really :-/

Ok, pfewww :)


> Here I'm referring to three schemas: two built in fixed schema and one
> configurable:
>
>  1. The "core" schema containing the standard schema elements defined
> in the LDAP RFCs(objectClass, cn, sn, etc)

Ok. In OpenLDAP and ADS, we have a few base schemas : 'core' for
OpenLDAP, plus 'system', 'apache' and 'apache-meta' for ADS. It's
difficult to use less than that, I guess it's pretty much the same for
OpenDS, except that you only have 'core'

They all contain base elements, plus some specific ones in our case.
The reason why they are separated is that w edon't think it's a good
idea to mix schema elements in one big phat schema file.


>  2. The "empty" schema which contains no schema elements but fakes up
> attribute type definitions on demand (the core schema does this as
> well for attribute types that it does not find). I'm not sure of
> the value of this schema - but it's interesting to have I suppose :-)

We have the same kind of schema, named 'other'. Useful.

>  3. The global default schema - this can be modified by the
> application at start up and is the one used for all operations
> that require a schema but where the caller has not provided one.
> For example, we have: DN.valueOf(String) and DN.valueOf(String,
> Schema) --- the first uses the default schema. By default the
> default schema is the core schema.

I don't really see what this global default schema can be good for
(it's not an opinion, it's just a question). In my mind, we always
have to load 'core', so this is the base schema anyway.

> Then we allow additional schemas to be constructed via a SchemaBuilder or
> downloaded from a Directory Server via the Connection API.

SchemaBuilder : close to SchemaManager :)

Let's try to sumarize, because I think we are tainted by our
implementation (which is plain normal ...) :

- what I call Schema is a file (or an instance of this file),
containing AT, OC, ..., and used internally as a container for the
SchemaObjects (AT, OC...)
- a SchemaObject is an instance of AT, OC, MR, etc
- the SchemaManager in our case is the class responsible for any
schema manipulation (including addition or removal of SchemaObjects,
or full Schema). It seems to be close to your SchemaBuilder, except
that in your case, it creates a Schema, which is the global container
(my understanding).

What I envision is that, if we keep the Schema as a container for some
set of SchemaObject, then we need some SchemaObjects container which
can be see by the client as the whole set of SchemaObjects he can
uses.

Now the fact that you call this global container "schema" conflicts
with the file containing a subset of SchemaObjects I call "Schema"
too. We have two solutions here :
1) We use another name for this global container
(SchemaHandler/Container/manager)
2) I rename the Schema to SchemaFile or SchemaContainer, and the
Schema is the global container.

Frankly, I don't like SchemaManager as a name exposed to users, as
they know about it as the Schema ( as a whole ), and I think that the
subdivision of SchemaObjects in what we called 'Schema' is just
implementation dependant, and I would rather rename those containers
SchemaContainer/File.

I'm quite sure you will lean toward this solution, I just want to be
sure that others agree with this vision, or not.

thanks !

>
> Does that make sense?
>
> I'll come back to your other points tomorrow.
>
> Matt
>
>



-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com


Some rennaming

2010-01-04 Thread Emmanuel Lecharny

Hi guys !

Happy new years first !

Ok, since last december when we started to discuss about naming, we have 
had a lot of work to finish on our side, but now that we are almost 
done, we can move on and do some basic renaming on ADS client API to 
stick with what OpenDS team has selected, and to what we agreed on.


- LdapDN will be renamed to DN
- Rdn will be renamed to RDN
- AttributeTypeAndValue (ouf...) will be renamed to AVA.

More to come !

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Ready for some major changes in ADS

2010-01-08 Thread Emmanuel Lecharny

Hi guys,

after months of hard work, we now have a working SchemaManager, and the 
code has been moved back to trunk. We are now ready to do some renaming. 
So far, some renaming has already been done :


AttribyteTypeAndVaue has been renamed AVA

The next step will be to rename LdapDN to DN and Rdn to RDN.

I think we should then discuss about the DN, RDN and AVA methods.

wdyt ?

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




[DN] Existing API review

2010-01-12 Thread Emmanuel Lecharny

Hi,

yesturday, I conducted a review on the existing APIs for the DN class :
- Name/LdapName (JNDI) (I will call it JNDI)
- jLdap/LdapSdk (I will call it LSD)
- ApacheDS (ADS)
- OpenDS (ODS)
- UnbounID (UID)

There are some important differences. There are two sets of API,
depending on the existence of a constructor, or not.

- API having a constructor :
JNDI,
ADS,
UID

- API not having a constructor :
LSD,
ODS (ODS uses a static method valueof() to produce a DN)

IMHO, I really think that users prefer having a constructor over none or
a static factory. There are three rasons for that :
1) Most of LDAP users are using the JNDI API, which has a LdapNAME()
constructor
2) In Java, it's pretty natural to create objects through constructor.
3) I'm not sure that handling a cache for DN is a valuable trick, as it
leads to some contention and the need to manage this cache in a
muli-threaded environement (this has to be carefully evaluated)

I think that we should have some basic constructors, and if the cache is
proven to be valuable, then we can extend the API by adding the valueof(
... ) method.

The base constructor we can have are probably something like:
DN()
DN(String dnStr)
DN( RDN... rdns)
DN( RDN rdn, DN parent)

Thoughts ?

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com





Re: [DN] Existing API review

2010-01-14 Thread Emmanuel Lecharny

Matthew Swift a écrit :




public DN(String dnStr) {
 return valueOf( dnStr );
}


Nothing will prevent you from writing something like that, but the 
compiler will prevent you from compiling it. Get some sleep! ;-)

Doh !!! Yeah, or maybe some stronger coffee ;)


--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




DN class discussion summarized on the wiki

2010-01-17 Thread Emmanuel Lecharny

Hi guys,

I have summarized a part of the discussion on this wiki page :

http://cwiki.apache.org/confluence/display/DIRAPI/DN+API

I just tried to gather what we agreed on, and put it on this page. Feel 
free to comment it either directly on this page (add a comment at the 
end of the page), or on this mailing list.


Sorry if I didn't reflected exactly what we discussed, I just tried to 
get it clean at first. It's just a work in progress in any case.


Next step is to discuss about the operations on a DN.

Thanks !

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




About the Control interface

2010-01-24 Thread Emmanuel Lecharny

Hi guys,

as I'm working on the messages, I have looked at the Control Interface. 
Here is the way it's used in all the different APIs :


ADS :
we used the JNDI interface, and we will change to switch to a LDAP API 
Control


jLdap/LDAPSdk
=
class :
 LDAPControl

constructors :
 LDAPControl()
 LDAPControl(String, boolean byte[]))

methods :
 getID()
 getValue()
 isCritical()
 newInstance(byte[])
 clone()


JNDI

interface :
 Control

methods :
 getEncodedValue()
 getID()
 isCritical()


ODS
===
abstract class :
 Control

constructors :
 Control( String, boolean)

methods :
 getOID()
 getValue()
 hasValue()
 isCritical()


UID
===
class :
Control

constructors :
 Control(String)
 Control(String, boolean)
 Control(String, boolean, ASN1OctetString)

methods :
 encode()
 equals( Object )
 getControlName()
 getOID()
 getValue()
 hasValue()
 isCritical()


Checking all those implementations, I would suggest that we stick with 
something like :


interface Control


Not sure we need a class, when most of the controls will be named, like 
VLVControl, PageSearchControl, ...
ODS define an abstract class, which means nobody can create an instance 
of it. At this point, I think it's probably better to go for an 
interface, hidding the asbtract class to the client.



constructors :

No need of them, if it's an interface. From the server POV, this will be 
an issue, as we must be able to create Controls while decoding them and 
we don't necessarily know if the control will be supported or not. We 
will probably need an intermediate ControlImpl and an AbstractControl 
class in order to deal with this, but from the Client POV, this is nt 
relevant



methods :
 getOid() or getOID().
 getValue()
 isCritical()


Those three methoda re the bare minimum we need from the client side. 
I'm not sure that the hasValue() method is necessary, when the 
getValue() returning a null value will provide the same result.



Thoughts ?


--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Control wiki page

2010-01-25 Thread Emmanuel Lecharny

Hi,

I have added this page on the wiki :
http://cwiki.apache.org/confluence/display/DIRAPI/Control

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Re: About the Control interface

2010-01-25 Thread Emmanuel Lecharny

Matthew Swift a écrit :


   GenericControl(String oid) // non-critical, null value
   GenericControl(String oid, boolean isCritical) // null value
Makes sense to add this constructor, but for Control with *no* value 
(semantically more accurate, compared to *null* value).

   GenericControl(String oid, boolean isCritical, ByteString bytes)

byte[] fits well, I think.




The Control API must distinguish between null values (i.e. value not 
present) and empty values (i.e. value present but zero-length).

Absolutely. I mis-judged this need, so we should add this method :

boolean hasValue();


I don't know if it is out of scope for now, but do we want to support 
extensibility? In particular, how can client applications implement 
their own controls? There are two main issues here that I have 
encountered:


  1. Decoding of response controls: if I have a response control whose
 type is "MyControl" do I want the LDAP SDK to automatically decode
 it to this type? Or will the client application have to do it.
 Here's some pseudo code to illustrate my point:

  // Result contains a MyControl response control.
  Result result = connection.add(entry);

  // Option #1: Uses an internal map of Control implementation
 classes -> OID + decoder
  MyControl control = result.getControl(MyControl.class);




  // Option #2: Uses an internal map of OID -> decoder
  MyControl control = (MyControl) 
result.getControl(MyControl.OID);


  // Option #3: No internal map - client has to manually decode
  Control control = result.getControl(MyControl.OID);
  MyControl myControl = new MyControl(control);

 I prefer the first approach for simplicity but it requires a
 public API for registering Control implementations (as does option
 #2) or use introspection and require that all implementations
 provide an OID field and a constructor having a single Control
 argument. Option #3 is quite verbose for clients IMO.

 I think that it's safer if the request/response API decodes the
 Control each time rather than caching the decoded control. This
 will make it possible to support immutable request/responses.

 If it sounds like I getting ahead here, the point of this issue is
 that if we want to provide an simple decoding mechanism like #1
 then we will need to have some way for the SDK to be able to
 decode the Control. This means either having a registration
 process, or using introspection and having a well defined
 constructor and OID field.

 The same problem will present itself for the following API features:

 * decoding extended responses

 * decoding intermediate responses

 * decoding request controls (server-side so out of scope)

 * decoding extended requests (server-side so out of scope)

  2. Encoding/decoding controls: many control values are encoded using
 ASN1. Do we want to provided ASN1 support? This will also apply
 for new extended operations.

I think that these questions are only applicable if we decide to 
support extensibility.
Well, IMO, from the client side, these issues can occur only if the 
provided API does not support some of the server's Controls. In this 
case, the user will have to create his own Control, implementing the 
Control interface, and do the decoding himself. What the API will 
generate is a instance of Control where the ID, criticality and value 
are stored as opaque elements - especially for the value -. Up to the 
user to translate this instance to its own control.


I'm not sure that providing anything more complex ATM is usefull. Who 
develops Controls, anyway ?



--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




About Delete operation

2010-02-04 Thread Emmanuel Lecharny

Hi,

LDAP protocol does not allow someone to delete a full tree with a delete
operation. Microsoft added a control (1.2.840.113556.1.4.805 - subtree
delete) to provide such a feature. ADS and OpenDS both support it.

My question is : should we have a specific deleteTree() method in the
API, or should we expect the user to add the subtreeDelete control to a
standard DeleteRequest in order to do the same thing ?

Right now, we have implemented a programmatic approach of the subtree
delete operation this way :
- if the server supports the subtree delete control, then send the del
request with this control
- else recursively delete all the children

This is a very costly approach, as there is no way to be sure that an
entry is a leaf or has some children but reading the entry (or trying to
delete each entry, and if unsuccessful, consider that the entry has
children, and recurse).

An alternative would be to either use the Control if the server support
it, or to throw an excpetion if it does not.

wdyt ?

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com





Entry API

2010-02-04 Thread Emmanuel Lecharny

Hi,

here are some preliminary thoughts about the Entry class.

The Entry class
---

It's the base data structure representing an element stored into a LDAP 
server. It has a name (a DN) and some attributes.


All the existing API use the same name, Entry (or LDAPEntry), except 
JNDI which has no such class (it uses Attributes but without a DN) and 
this class contains at least those two inner elements :

- a DN
- a set of Attribute

There is some difference though as this element is either an Interface 
(ADS, ODS) or a Class (UID, jLdap)


ODS define an implementing class named SortedEntry, which does not make 
a lot of sense, IMO. ADS class hierarchy is even more complex, as there 
are two lower interfaces (ClientEntry and ServerEntry) with two 
implementing classes (DefaultClientEntry and DefaultServerEntry). 
Overkilling … (and will be rewritten soon)


All in all, I'm wondering if it's a good idea to have an interface 
instead of a class, as it does not make a lot of sense to implement some 
different version of such an object.


Constructors


Here are the current implementations :

ADS :
DefaultClientEntry()
DefaultClientEntry(LdapDN)
DefaultClientEntry(LdapDN, EntryAttribute...)
DefaultClientEntry(LdapDN, String...)
DefaultServerEntry(SchemaManager)
DefaultServerEntry(SchemaManager, Entry)
DefaultServerEntry(SchemaManager, LdapDN)
DefaultServerEntry(SchemaManager, LdapDN, AttributeType, String)
DefaultServerEntry(SchemaManager, LdapDN, AttributeType...)
DefaultServerEntry(SchemaManager, LdapDN, ServerAttribute...)
DefaultServerEntry(SchemaManager, LdapDN, String...)

jLdap :
LDAPEntry()
LDAPEntry(String)
LDAPEntry(String, LDAPAttributeSet)

JNDI :
N/A

OpenDS :
SortedEntry()
SortedEntry(DN)
SortedEntry(Entry)
SortedEntry(String)
SortedEntry(String...)

UID :
Entry(DN)
Entry(DN, Attribute...)
Entry(DN, Collection)
Entry(String)
Entry(String, Attribute...)
Entry(String, Collection)
Entry(String...)


Quite complex :/ The problem here is that we would like those entries to 
be schema aware. The question is : how to make it simple for the user to 
create a schema aware entry? Either the entry comes from the server he 
is connected to, or he creates new entries on the client before sending 
them to the server. In both cases, the entry has to know about the schema.


Let's first assume that it's the case. The minimal list of constructors is :
Entry() : an empty constructor
Entry(DN)
Entry(String) : The DN is a string
Entry(DN, Attribute…)
Entry(String, Attribute…)
Entry(String…) : A special constructor which takes a list of strings 
representing a LDIF form of the entry


All those constructors will assume that the default schema will be used.

We can then inject a Schema by adding it to the constructor :
Entry(SchemaManager) : an empty constructor
Entry(SchemaManager, DN)
Entry(SchemaManager, String) : The DN is a string
Entry(SchemaManager, DN, Attribute…)
Entry(SchemaManager, String, Attribute…)
Entry(SchemaManager, String…) : A special constructor which takes a list 
of strings representing a LDIF form of the entry


Thoughts ?

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Re: Entry API

2010-02-06 Thread Emmanuel Lecharny

On 2/6/10 12:34 AM, Matthew Swift wrote:
I totally agree with Alex. Entry MUST be an interface - I feel very 
strongly about this :-)

this is probably why ODS and ADS Entry are both interface :)

Alex is right here : having it an interface does not obliterate the future.


In ODS we take the Collections API approach by having Entry defined as 
an interface and then providing several sub-implementations based on 
the storage/retrieval model the implementation provides. We only have 
one implementation so far which is a TreeMap based Entry called 
SortedEntry (it may have been better to call it TreeMapEntry). This 
gives nice user-friendly behavior in GUIs for example since our 
AttributeDescription (the keys in the TreeMap) have a sort order: 
objectClass first, then user attributes, then operational attributes, 
each group sorted alphabetically. 
IMHO, I find this a bit dubious that any user will need to get 
attributes sorted. In most cases, you simply pull a specific attribute 
from an entry, and rarely use an iterator on attributes which needs them 
to be ordered. Anyway, I see no reason either not to propose such an 
implementation. I just think it should not be the base implementation 
for the API users.

However, this is not so good in other use cases:

   * other tools would be better using a LinkedHashMap instead in order
 to preserve the original ordering

   * proxy like apps are unlikely to need to query the entry, just
 reserialize it, so they need an implementation which is tuned for
 decode/encode

   * entry caches need an implementation tuned for memory footprint and
 which is read-only

   * a tool such as searchrate would need a "null" entry implementation
 - it throws away any attributes you attempt to store in the entry
 (typically you don't want a searchrate tool to decode every
 SearchResultEntry into a TreeMap/LinkHashMap based Entry).


That's just a few example use cases and I can think of a few others too.
Yeah, and this is why Entry *must* be an interface, I now agree. 
Sometime you have to be the devil advocate...


I also agree with the requirement to have an EntryFactory interface. 
This can be passed to search operations in order to determine which 
implementation is used.
Question is : should we use this factory to define a default 
implementation which should not be visible to the users, and use a 
specific object (like SortedEntry) for specific needs ?


I recently raised these RFEs to the ODS SDK which proves that I am not 
making this up as I go along: ;-)


   https://opends.dev.java.net/issues/show_bug.cgi?id=4425
   https://opends.dev.java.net/issues/show_bug.cgi?id=4426

I would make those proposal a part of an extended API. KISS...


As for naming, I am a bit against having a "default implementation" 
called something like EntryImpl since the name does not communicate 
anything about how it works (is it sorted, original order, etc?).
In my mind, it does not have to convoy any information about the entry 
but the DN and the Attributes. Every other behavior should be delivered 
though subclasses. If we use a factory to create an Entry, then it may 
even be not visible.


Regarding schema, I have implemented the following policy in our SDK:

   * DNs need a schema for decoding

   * Attribute descriptions need a schema for decoding

   * Filters need a schema during compilation (out of scope here as
 this is a server side thing)
Well, you can control the filter before sending the request to the 
server. It can save CPU on the server at a small price on the client...


   * Entries need a schema for schema validation

   * IIRC all other objects in the SDK either do not need schema (e.g.
 SearchScope) or are containers of some sort containing DNs,
 attributes, etc (e.g. entries, requests, etc). Containers:

 o provide methods which accept pre-decoded objects (DN,
   AttributeDescription, Attribute, etc) which are already
   associated with a schema

 o provide ease-of-use String based methods (e.g.
   Entry.setDN(String))

 o have no intrinsic Schema associated with them. Otherwise,
   consider what it means if an Entry did have an intrinsic
   Schema - what would happen if I call Entry.setDN(DN) using a
   DN decoded using a different schema? Should an exception be
   thrown?

 o attempts to use String based methods which require some form
   of decoding (e.g. Entry.setDN(String)) always use the global
   default schema.
Not sure if you consider Entry as a container (ie "have no intrinsic 
Schema") or if "Entries need a schema for schema validation".


In your third point about containers, if an entry has an associated 
schema which is different from the schema used to create the DN, then I 
think we should throw an exception All in all, schemas are associated 
with a subtree, clearly defined by the DN, so the entry's schema 

Ldap Operations

2010-02-06 Thread Emmanuel Lecharny

Hi !

Time to discuss about Ldap operations.

We have two kind of messages, Requests and Responses. They both are 
LdapMessages. Let's start with Requests


Requests :
--


The list of existing Requests is :

Abandon
Add
Bind
Compare
Delete
Extended
Modify
ModifyDn
Search
Unbind

Some of them can be abandoned, two can't (Abandon, and Unbind)

Abandonable requests :

Add
Bind
Compare
Delete
Extended
Modify
ModifyDn
Search


Responses :
---

Before IntermediateResponse was introduced in RFC 4511, we were able to 
distinguish between three kind of requests accordingly to their 
associated responses  :

- Requests with no expected responses : Unbind, Abandon
- Requests with a single expected response : Add, Bind, Compare, Delete, 
Extended, Modify, ModifyDN

- Requests with a multiple expected response : Search.

Since RFC 4511 introduced the Intermediate response, things have 
changed. Any request expecting a response may have a multiple response, 
assuming that it has been sent with a control which semantic implies 
that we may receive zero to many intermediate responses.


We cannot then distinguish requests in more than two kinds : those with 
no response, and those with multiple responses.



Hierarchy :
--

In order to reflect this, we can define a pretty simple hierarchy of 
 ad [classes] :



  ^
  |
  +-- 
  |  ^
  |  |
  |  +-- 
  |  +-- 
  |
  +-- 
 ^
 |
 +-- 





 <--+
  \
   +-- [AddRequest], [BindRequest], 
[CompareRequest], [DeleteRequest], [ExtendedRequest],
  /[ModifyRequest], [ModifyDnRequest], 
[SearchRequest]

 <--+


 <-- [AbandonRequest], [UnbindRequest]

 <-- [AddResponse], [BindResponse], [CompareResponse], 
[DeleteResponse], [ExtendedResponse],

   [ModifyResponse], [ModifyDnResponse], [IntermediateResponse]

 <-- [SearchResultEntry], [SearchResultReference], 
[SearchResultDone]



Thoughts ?

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Sync/Asyc operations

2010-02-10 Thread Emmanuel Lecharny

Hi,

a quick mail about operations, as we talked about some aspect of it with 
Ludovic a couple of time, and we need to have some track of those 
discussions.


So we agreed that each operation should be synchronous *and* 
asynchronous. Having async operation is of major importance for 
operation that one user wants to abandon. Something like :


Future responseFuture = connection.search( blah );
int i = 0;

while ( responseFuture.hasMore() )
{
  Response response = responseFuture.get();
  i++;
  ...

  if ( i > 10 )
  {
// Ok, enough
responseFuture.abandon();
break;
  }
}

is easier to use than having to declare a new thread to abandon a request.

There are some huge differences between OpenDS, UID and ADS in this area :
- ODS has two LdapConnection objects : one for sync operations, one for 
async operations.
- UID has two methods for each operation. For instance bind() and 
asyncBind()
- ADS has a bit more complicated system which implise that a listener to 
be injected in the method to make it async : bind( bindReques, listener) 
=> async. bind( bindRequest ) => sync.


I think that UID approach is the most user friendly. Most of the case, 
users will use the sync methods. I don't like having 2 LdapConnection 
object, as it forbids the user to switch from sync to async. The ADS 
approach, based on listener, is way too complex.


thoughts ?

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Connection : Simple Bind operation

2010-02-11 Thread Emmanuel Lecharny

Hi,

I just checked the way all the API handle the simple Bind() operation. 
Here is a sum up :


ADS :
-
see later...

jLdap :
---
synchronous :
* bind(int, String, byte[])
* bind(int, String, byte[], LDAPConstraints)

asynchronous :
* bind(int, String, byte[], LDAPResponseQueue)
* bind(int, String, byte[], LDAPResponseQueue, LDAPConstraints)

LDAPConstraints will contain the controls.
LDAPResponseQueue is used for asynchronous operation


JNDI :
--

JNDI Bind operation is totally different. It's semantically another 
beast. A LDAP Bind on JNDI is done through the creation of a Context, 
and the user/credentials are passed in a hashtable. We don't want to go 
there ...


ODS :
-
synchronous :
* Connection.bind(BindRequest)
* Connection.bind(String, String)

asynchronous :
* LdapConnection.bind(BindRequest, ResultHandler)

Beside the fact that it's not obvious that LdapConnection class means 
'asynchronous', a password may be a byte[] so we won't be able to easily 
bind in this case (a user will have to create a BindRequest). Anonymous 
bind needs to pass null values to the bind operation.


UID :
-
synchronous :
* bind(BindRequest)
* bind(String, String)

No asynchronous bind.

Summary :
-
This is really an area where the APIs differ a lot. If we come back to 
the RFC, a Simple Bind operation has 3 valid forms and one invalid :

user = null, password = null : anonymous bind
user != null, password = null : unauthenticated bind
user = null, password != null : invalid
user != null, password != null : simple authentication

In any case, the password is an Octet String, ie a byte[]. The user is 
always a DN when doing a simple bind.


Some last consideration : if we are to support asynchronous operations, 
then we need to make this explicit.


I suggest we keep it simple from the user pov, considering that :
- users will mainly do synchronous operations
- anonymous bind must be easy to code
- we want to make it explicit that the async mode is used
- and we don't want zillion of methods.

So every method bind(...) will have a equivalent async method 
bindAsync(), the anonymous bind will be a bind() method without 
parameters, the password can be either a String or a byte[], and the 
user can be either a String or a DN :


synchronous :
* bind()  anonymous bind
* bind( String userDN, String password ): simple bind (if the password 
is null, this will be the unauthenticated bind)

* bind( String userDN, String password )
* bind( DN userDN, String password )
* bind( String userDN, byte[] password )
* bind( DN userDN, byte[] password )
* bind( BindRequest )

asynchronous :
* bindAsync()  anonymous bind
* bindAsync( String userDN, String password ): simple bind (if the 
password is null, this will be the unauthenticated bind)

* bindAsync( String userDN, String password )
* bindAsync( DN userDN, String password )
* bindAsync( String userDN, byte[] password )
* bindAsync( DN userDN, byte[] password )
* bindAsync( BindRequest )

This is currently what we have in ADS, not because it's better, but 
because we have redesigned the API after having written this mail (the 
previous API was, hmmm. ok. don't ask ;)


thoughts ?

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Re: Connection : Simple Bind operation

2010-02-11 Thread Emmanuel Lecharny

On 2/11/10 7:59 PM, Stefan Seelmann wrote:

Emmanuel Lecharny wrote:


In any case, the password is an Octet String, ie a byte[]. The user 
is always a DN when doing a simple bind.


At least to Active Directory you can bind with a username like 
u...@domain. So the API should allow a non-DN user.
Bloody M$ !!! Yeah, you are right. Then the bind( String, String/byte[]) 
should not check that the user is a valid DN.


Some last consideration : if we are to support asynchronous 
operations, then we need to make this explicit.


I suggest we keep it simple from the user pov, considering that :
- users will mainly do synchronous operations
- anonymous bind must be easy to code


what if the user forgets to call a "bind" method but just calls 
another operation? Should we check that at the client? Should we do an 
implicit anyonymous bind?
This is perfectly valid. You can do a straight search() without having 
done a previous bind() : the server should assume that it's an anonymous 
bind.



- we want to make it explicit that the async mode is used
- and we don't want zillion of methods.

So every method bind(...) will have a equivalent async method 
bindAsync(), the anonymous bind will be a bind() method without 
parameters, the password can be either a String or a byte[], and the 
user can be either a String or a DN :


synchronous :
* bind()  anonymous bind
* bind( String userDN, String password ): simple bind (if the 
password is null, this will be the unauthenticated bind)

* bind( String userDN, String password )
* bind( DN userDN, String password )
* bind( String userDN, byte[] password )
* bind( DN userDN, byte[] password )
* bind( BindRequest )


I'm not sure if we really need the variants with a byte[] password. 
The user has to type in the password somewhere, so in most cases the 
password is a string. If the user really wants to do it s/he must use 
a BindRequest.
That's an option, sure. In some case, the password can also be a binary 
value the user won't type (like with fingerprints, for instance). You 
have so many cool devices out there those days !!!



asynchronous :
* bindAsync()  anonymous bind
* bindAsync( String userDN, String password ): simple bind (if the 
password is null, this will be the unauthenticated bind)

* bindAsync( String userDN, String password )
* bindAsync( DN userDN, String password )
* bindAsync( String userDN, byte[] password )
* bindAsync( DN userDN, byte[] password )
* bindAsync( BindRequest )


Is there some handle returned by the async methods?

Yes, you get back a Future.


--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Re: Connection : Delete operation

2010-02-11 Thread Emmanuel Lecharny

On 2/11/10 6:03 PM, Kiran Ayyagari wrote:


hi guys,

   Here is a summary about the delete operation handled by various 
client SDKs


jLdap :
---
synchronous :
* delete(String dn)
* delete(String dn, LDAPConstraints cons)

asynchronous :
* delete(String dn, LDAPResponseQueue queue)
* delete(String dn, LDAPResponseQueue queue, LDAPConstraints cons)


UID :
-
synchronous :
* delete(String dn)
* delete(DeleteRequest deleteRequest)
* delete(ReadOnlyDeleteRequest deleteRequest)

asynchronous :
* asyncDelete(DeleteRequest deleteRequest, AsyncResultListener 
resultListener)
* asyncDelete(ReadOnlyDeleteRequest deleteRequest, AsyncResultListener 
resultListener)



ODS :
-
synchronous :
* delete(DeleteRequest request)
* delete(String name)

asynchronous :
* delete(DeleteRequest request, ResultHandler handler)

JNDI :
--
this is completely a different beast to tame ;)
* Context.unbind()
* Context.destroySubcontext()


The proposed API for delete operation in ADS is

ADS :
-
synchronous :
* delete( String dn )
* delete( LdapDN dn )
* delete( DeleteRequest delRequest )

asynchronous
* deleteAsync( String dn )
* deleteAsync( LdapDN dn )
* deleteAsync( DeleteRequest delRequest )

thoughts?
Sounds good. as usual, this is not the ADS proposal (we currently don't 
have the deleteAsync methods), but what we think is ok from the user 
POV. ADS has taken anther road atm (but will move forward and change 
what is currenttly done).



--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Connection and authentication knowledge

2010-02-23 Thread Emmanuel Lecharny

Hi,

should we add some method in LdapConnection to inform the user about the 
authentication ?


ie, isAnonymous(), isSimpleAuth(), isSaslAuth(), or even better 
getAuthenticatedUser() returning the principal ?


// Anonymous connection
connection.bind();

if ( connection.isAnonymous() ) {
  System.out.println( "anonymous" );
}

// Authenticated connection
connection.bind( "uid=admin,ou=system", "secret" );

if ( connection.isAnonymous() ) {
  System.out.println( "anonymous" );
} else if ( connection.isSimpleAuth() ) {
  System.out.println( "SimpleAuth for : " + 
connection.getAuthenticatedUser() );

}

wdyt ?

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Handling M$ specification violations

2010-02-23 Thread Emmanuel Lecharny

Hi,

M$, as usual, is violating many LDAP RFCs. For instance, you can send a 
simple BindRequest where the user name is *not* a DN.


I guess we will have to bend the API to accept such crapity...

wdyt ?

M$

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Re: Handling M$ specification violations

2010-02-26 Thread Emmanuel Lecharny

On 2/23/10 10:06 PM, Matthew Swift wrote:
I think so - I realize that our OpenDS SDK needs to cope with this as 
well :-(


It makes me wonder what else could be violated? Should we permit 
non-DNs for all operations? 

IMO, no.

E.g. modifying the entry "joe.blo...@example.com"?  It seems a bit 
inconsistent to be lax in only one part of the protocol but not 
others. ;-)
There is a difference with the Bind operation DN : for M$, it makes 
sense to enforce their own rule, as they can't ask people to type a DN 
to login (even if they could have used SASL instead of a Simple 
BindRequest). But AFAIK, I don't think you need to 'fix' some other 
request to accept something else than a DN.


My preference is to encourage conformance where possible. What other 
known violations are there other than the bind DN?
You can rad this very interesting paper from Symas : 
http://www.symas.com/documents/Adam-Eval1-0.pdf


One of the major violation, beside the use of a non-DN in a SimpleBind 
operation is the fact that anonymous authent is not allowed on AD/ADAM 
by default, but this should not be a problem from the API pov, and 
another one is the retrieval of MV attributes that may need a special 
treatment when here are more than 1500 values (and I guess we have to 
deal with this problem...).

--

Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




LdapDN renamed to DN

2010-03-05 Thread Emmanuel Lecharny

Hi,

accordingly to the discussions we had here, we renamed our LdapDN class 
to DN.


Just FYI.

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




DN wiki page updated

2010-03-05 Thread Emmanuel Lecharny

Hi guys,
I have updated this page :
http://cwiki.apache.org/confluence/display/DIRAPI/DN+API

It now contains all the methods I think we need for DN. It's a mix 
between all the API, I just picked what I think is the best from all of 
them, so don't be jealous, it's not all based on ADS or ODS :)


Feel free to comment, it's not yet implemented anywhere.

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Re: LdapDN renamed to DN

2010-03-05 Thread Emmanuel Lecharny

On 3/5/10 2:23 PM, Ludovic Poitou wrote:

Hi Emmanuel,

I had seen the message on the Apache Mailing lists.
I'm looking forward to see Apache ldap lib 0.1.0 ;-)
   

It will be out on monday or tuesday, I think.

It's a *very* preliminay version, the one we use internally for a lot of 
tests, but there is *no* guarantee it will not move a lot until we reach 
the final API. It's more a proof ofconcept than anything else, I 
strongly suggest that nobody use it atm, except to comment it.


As usual, I know that by strongly suggesting not to use it, it's really 
like telling adam and eve not to touch the forbidden fruit ;)


/me, snake...

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




About exceptions

2010-03-12 Thread Emmanuel Lecharny

Hi,

it's about time to talk about exceptions, as many methods will throw an 
exception, and it would be good to know what to throw !


We should first have a base exception, and I suggest using 
LdapException. Evey other exception will inherit this one.


The second point is that the LDAP protocol define a list of errors, and 
we should map an exception to those errors. This has been done for JNDI, 
and it's a pretty good idea to keep our exception hierarchy close to the 
JNDI one.


AFAICT, neither OpenDS nor Unboundid define an exception hierarchy. 
Something I don't find useful is a method throwing a 
NullPointerException (IMO, this is totally useless, and certainly not an 
exception you want to add in the list of thrown exceptions for a method 
...).


jLDAP defines a few exceptions, with a base LDAPException class.
LDAPReferralException, LDAPLocalException are subclasses and used for 
some specific needs.



All in all, JNDI's exception system is pretty decent, and I think we 
should mimic it, but without implementing or extending the JNDI classes 
(something ADS is doing, and it collides with the renaming of DN, as 
it's not anymore a NAME extension).

thoughts ?

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Immutable objects, what's best ?

2010-03-13 Thread Emmanuel Lecharny
Hi,

we have many objects that we want to be immutable. What's the best solution
to produce  those immutable objets ?

- For DN, we would like to use valueOf(), and the DN() constructor, but no
setter
- For Entry, a constructor is not enough, as we may have to inject new
attributes. We may need to have two different classes, one immutable, one
mutable. The immutable class could be associated with a factory, or we can
use a constructor with the list of attributes as a parameter.
- For attributes, we have the same problem : we may have more than one
value.

DO any of you guys have a strong opinion ?

-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com


Re: Immutable objects, what's best ?

2010-03-14 Thread Emmanuel Lecharny

On 3/14/10 9:46 AM, Stefan Seelmann wrote:

Emmanuel Lecharny schrieb:
   

Hi,

we have many objects that we want to be immutable. What's the best solution
to produce  those immutable objets ?

- For DN, we would like to use valueOf(), and the DN() constructor, but no
setter
- For Entry, a constructor is not enough, as we may have to inject new
attributes. We may need to have two different classes, one immutable, one
mutable. The immutable class could be associated with a factory, or we can
use a constructor with the list of attributes as a parameter.
- For attributes, we have the same problem : we may have more than one
value.

DO any of you guys have a strong opinion ?
 

Entry and Attribute object created by the user of the API shouldn't be
immutable. As user of the API I want to create an Entry object and add
attribute and values to it. So the API must provide setters.
   
I came to the same conclusion, but with another idea : create two Entry 
objects, one for the client, one for the server. It's close to what we 
have on ADS, but the more I think about it, the more I find it complex 
and bothersome.
Now, let's think about another option : what if we add a parameter in 
the constructor to create Immutable Entries ? Something like :
Entry immutableEntry = new EntryImpl( DN, true ); // True => the entry 
is immutable ?



So I think if Entry and Attribute are interfaces we just define the
getter methods.
   
Smart ! That could do the trick, sure ! But is it better than the 
previous solution?


My idea was to forbid a setter to be called if the Immutable flag is 
set, a solution I find a bit more strong than hiding the setter though 
the interface, but it forces the user to add a flag to the constructor.


Again, what do you think is the best approach ?

The default implementations of those classes (e.g. ClientEntry and
ClientAttribute) additional have setters the user can use when
constructing the objects.

The Entry objects returned from the API (e.g. from a search) should be
immutable to protect them from being casted by the user, e.g. by
wrapping a created ClientEntry into an ImmutableEntry implementation.
   
Hmmm... Do you suggest that we should define 2 different classes ? (one 
immutable, one mutable). Wouldn't it be better to have one single 
implementation, with a limited interface, forcing the user to cast to be 
able to use the setters ? Or should we have a ClientEntry class 
extending a ServerEntry class ?



--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Re: About exceptions

2010-03-14 Thread Emmanuel Lecharny

On 3/14/10 10:56 AM, Kiran Ayyagari wrote:


from the recent experience of migrating test cases to client-api
have observed that unlike jndi we return result codes and I liked this
(the jndi exceptions rather give me a feeling like 'use exceptions for 
control flow', which is considered as a bad practice by many)


so +1 for returning result codes instead of exceptions

Yes, that's pretty obvious we should do that.

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Re: About exceptions

2010-03-14 Thread Emmanuel Lecharny

On 3/14/10 11:42 AM, Alex Karasulu wrote:

On Sun, Mar 14, 2010 at 10:23 AM, Stefan Seelmann  wrote:
   

Emmanuel Lecharny wrote:
 

Hi,

it's about time to talk about exceptions, as many methods will throw an
exception, and it would be good to know what to throw !

We should first have a base exception, and I suggest using
LdapException. Evey other exception will inherit this one.

The second point is that the LDAP protocol define a list of errors, and
we should map an exception to those errors. This has been done for JNDI,
and it's a pretty good idea to keep our exception hierarchy close to the
JNDI one.

AFAICT, neither OpenDS nor Unboundid define an exception hierarchy.
Something I don't find useful is a method throwing a
NullPointerException (IMO, this is totally useless, and certainly not an
exception you want to add in the list of thrown exceptions for a method
...).

jLDAP defines a few exceptions, with a base LDAPException class.
LDAPReferralException, LDAPLocalException are subclasses and used for
some specific needs.


All in all, JNDI's exception system is pretty decent, and I think we
should mimic it, but without implementing or extending the JNDI classes
(something ADS is doing, and it collides with the renaming of DN, as
it's not anymore a NAME extension).
thoughts ?
   

I agree that a exception hierarchy with a base LdapExcepton class makes
sense.

One important thing is to add the result code to the exception. In JNDI
you have to extract it from the exception message.

Another thing I don't like with JNDI is the handling of referrals and
search continuations. I think for referrals it makes sense to throw an
exception. But for search continuations we shouldn't throw an exception
but a SearchResultReference object should be returned.
 

+1

I also think the ability to pursue references should be a very easy
task for the coder. Chaining should be a construct built in and really
intuitive.  Don't know however how this can best be designed from the
API perspective.
   

Yeah, this has to be handled on the API side. Still have to think about it.
   

I also wonder if we need to generate an exception for all the result
messages. For example for an timeLimitExceeded or sizeLimitExceeded or
adminLimitExceeded result I think it is not necessary, the user can just
check the result code if s/he wants to handle that case.
 

I think the exception or perhaps a callback mechanism might be needed
here to cleanup or respond to these kinds of cases.  It's just a
matter of interrupting the flow so detection and handling can proceed.
We still need some kind of trigger to let the user know the time limit
for example has been exceeded.  Otherwise all code including the main
non-exceptional pathways will be cluttered with checks for these
cases.
   
I agree. Having to add try/catch to handle time ans size limit exception 
would be a real PITA. In any case, the last response will contain the 
resultCode, so I'm not sure that we shoud throw an exception in this case.


To be discussed further...


--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Re: Immutable objects, what's best ?

2010-03-14 Thread Emmanuel Lecharny

On 3/14/10 2:19 PM, Stefan Seelmann wrote:

Emmanuel Lecharny wrote:
   

On 3/14/10 9:46 AM, Stefan Seelmann wrote:
 

Emmanuel Lecharny schrieb:

   

Hi,

we have many objects that we want to be immutable. What's the best
solution
to produce  those immutable objets ?

- For DN, we would like to use valueOf(), and the DN() constructor,
but no
setter
- For Entry, a constructor is not enough, as we may have to inject new
attributes. We may need to have two different classes, one immutable,
one
mutable. The immutable class could be associated with a factory, or
we can
use a constructor with the list of attributes as a parameter.
- For attributes, we have the same problem : we may have more than one
value.

DO any of you guys have a strong opinion ?

 

Entry and Attribute object created by the user of the API shouldn't be
immutable. As user of the API I want to create an Entry object and add
attribute and values to it. So the API must provide setters.

   

I came to the same conclusion, but with another idea : create two Entry
objects, one for the client, one for the server. It's close to what we
have on ADS, but the more I think about it, the more I find it complex
and bothersome.
Now, let's think about another option : what if we add a parameter in
the constructor to create Immutable Entries ? Something like :
Entry immutableEntry = new EntryImpl( DN, true ); // True =>  the entry
is immutable ?

 

So I think if Entry and Attribute are interfaces we just define the
getter methods.

   

Smart ! That could do the trick, sure ! But is it better than the
previous solution?

My idea was to forbid a setter to be called if the Immutable flag is
set, a solution I find a bit more strong than hiding the setter though
the interface, but it forces the user to add a flag to the constructor.

Again, what do you think is the best approach ?
 

I don't like it if a setXXX() method is provided and if I call it some
"YouIdiotAreNotAllowedToCallThisMethodException" is thrown.

So IMO having the interface which provides read-only methods is best.

And if using the EntryImpl you have all the setters and the setters work.

Then you can obtain an immutable Entry from that EntryImpl, see below.

   

The default implementations of those classes (e.g. ClientEntry and
ClientAttribute) additional have setters the user can use when
constructing the objects.

The Entry objects returned from the API (e.g. from a search) should be
immutable to protect them from being casted by the user, e.g. by
wrapping a created ClientEntry into an ImmutableEntry implementation.

   

Hmmm... Do you suggest that we should define 2 different classes ? (one
immutable, one mutable). Wouldn't it be better to have one single
implementation, with a limited interface, forcing the user to cast to be
able to use the setters ? Or should we have a ClientEntry class
extending a ServerEntry class ?
 

I wouldn't call it ClientEntry and ServerEntry, sorry that I used that
name before ;-)

In the public API I would define an default implementation (not sure
about the name, we discussed some names before) which is mutable. This
implementation is used by the user because I don't think he wants to use
an immutable implementation.

The immutable implementation just works like the java.util.Collections
class, there are static methods like unmodifyableSet(Set set). So we can
have some Utils class which wraps the default mutable class into an
immutable. Or the default Entry implmentation could provide a method
"toImmutableEntry()". The immutable implementation shouldn't be part of
the public API.

wdyt?
   


Sounds good. I will update the wiki with such a proposal.


--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Updated wiki page for Entry

2010-03-14 Thread Emmanuel Lecharny

Here is a new page added for the entry API :

http://cwiki.apache.org/confluence/display/DIRAPI/Entry+API

It's not completely finished.

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Exceptions wiki page

2010-03-15 Thread Emmanuel Lecharny

Here is the current wiki page about exceptions :
http://cwiki.apache.org/confluence/display/DIRAPI/Exception+API

As usual, just a preliminary work.

Comments welcome !

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Pluggable Network layer

2010-03-15 Thread Emmanuel Lecharny

I have created an issue in JIRA :
https://issues.apache.org/jira/browse/DIRAPI-10

The idea is to allow the user to specify the IO layer he wants to use.

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




API packages

2010-03-18 Thread Emmanuel Lecharny

Hi,

I know it might be a bit premature, but we would like to discuss the 
package hierarchy at some point. Right now, we are just trowing some 
names and some methods, but all those guys will have to be put in 
packages, and it's probabmy a good idea to propose something now. At 
least, a starting point.


What we are dealing with can be sorted into a few categories :
- exceptions
- name (DN, RDN, etc)
- message (Bind, Add, Delete...)
- utils or commons
- ldif
- entry (Entry, Attribute...)
- schema

We may also have a few more sub-packages :
- message/extended
- message/control
- schema/comparator
- schema/normalizer
- schema/syntaxChecker

I may have missed some of them, the idea is just to bootstrap this 
reflexion.


thoughts ?


--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




DN and Exceptions

2010-03-18 Thread Emmanuel Lecharny

Hi,

i was studying the exceptions, and regarding DN, I think we could be a 
bit more specific. Right now, we are just throwing a 
LdapInvalidDnException, when we could have more than one kind of error :

- The normalization could fail
- The DN could be invalid
- An operation (add, etc) could be invalid

What abbot defining a DnException root, and three different exceptions 
like :

- DnNormalizationException
- DnParsingException
- DnOperationException
 all of them extending the DnException.

Does it make sense to you ?

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Re: Where can i get IntialContextFactory?

2010-03-21 Thread Emmanuel Lecharny

On 3/21/10 2:59 PM, Muralidhar Yaragalla wrote:

Where can I get the API for ApacheDS which contains the
IntialContextFactory?
   

Uh ?

InitialContextFactory is part of the JNDI API...

May be you have something in mind, can you be a bit more precise in your 
question ?


--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Re: Where can i get IntialContextFactory?

2010-03-22 Thread Emmanuel Lecharny

On 3/22/10 9:22 PM, Muralidhar Yaragalla wrote:

I don't understand what you are talking about? What suggestion I gave and
what question I should not ask. I am not asking any question. I am just
saying that tutorial should not be pointed as a piece of evidence when
talking about API. I think you somehow misunderstood this mail. Please don't
even bother to reply when you does not understand the context or mail. Just
waste of your and my time.
   
In fact, we didn't understood you first e-mail. So no wonder why we 
didn't understood the next few ones. I'm not even sure you understand 
your own question. Not an issue though. We probably live in parellel 
worlds, so have an happy life in your own.


--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




About DN.getAll()

2010-03-23 Thread Emmanuel Lecharny

Hi,

just a Q : should this method return the RDN fro left to right or from 
right to left ?


--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Re: About DN.getAll()

2010-03-23 Thread Emmanuel Lecharny

On 3/23/10 12:16 PM, Kiran Ayyagari wrote:

On 3/23/10 1:08 PM, Emmanuel Lecharny wrote:

Hi,

just a Q : should this method return the RDN fro left to right or from
right to left ?

left to right makes sense to me (it will also be aligned with 
getRdns() method )
Sorry, I was not clear enough. The JDNI getAll() method returns RDN from 
right to left, while getRdns() do the opposite, so my question.


To me, going from left to right makes more sense too anyway.

Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Attribute object definition

2010-04-19 Thread Emmanuel Lecharny

Hi guys,

I'm back from two weeks of vacations, and it's hard to come back to code 
... Anyway, coding is quite close to having vacations, so...


I have checked the existing APIs and how they implement the Attribute 
object. here is what we have :


- JNDI :
o an Attribute interface, a BasicAttribute implementation
o Implements Cloneable and Serializable
o A few constructors :
  BasicAttribute(String id)
  BasicAttribute(String id, boolean ordered)
  BasicAttribute(String id, Object value)
  BasicAttribute(String id, Object value, boolean ordered)

- jLDAP :
o no interface, a LDAPAttribute class
o Implements Cloneable, Comparable and Serializable
o A few constructors :
  LDAPAttribute()
  LDAPAttribute(LDAPAttribute)
  LDAPAttribute(String id)
  LDAPAttribute(String id, byte[] value)
  LDAPAttribute(String id, String value)
  LDAPAttribute(String id, String[] value)

- OpenDS :
o One interface, Attribute
o Many classes implementing this interface : AbstractAttribute, 
EmptyAttribute LinkedAttribute ( it seems that the ater is the one to 
use when creating a new Attribute) plus some wrappers 
(UnmodifiableAttribute, RenamedAttribute)

o Does not implement any extra interface
o Some constructors, none being schema aware :
  LinkedAttribute(Attribute)
  LinkedAttribute(AttributeDescription)
  LinkedAttribute(AttributeDescription, ByteString)
  LinkedAttribute(AttributeDescription, ByteString...)
  LinkedAttribute(AttributeDescription, Collection)
  LinkedAttribute(String)
  LinkedAttribute(String, Object)
  LinkedAttribute(String, Object...)

- UnboundID
o No interface, just one class : Attribute
o implements Serializable
o Many (too many) constructors :
  Attribute(String name)
  Attribute(String name, ASN1OctetString... values)
  Attribute(String name, byte[] value)
  Attribute(String name, byte[]... values)
  Attribute(String name, Collection)
  Attribute(String name, MatchingRule)
  Attribute(String name, MatchingRule, ASN1OctetString[])
  Attribute(String name, MatchingRule, byte[])
  Attribute(String name, MatchingRule, byte[]...)
  Attribute(String name, MatchingRule, Collection)
  Attribute(String name, MatchingRule, String)
  Attribute(String name, MatchingRule, String...)
  Attribute(String name, Schema, ASN1OctetString... values)
  Attribute(String name, Schema, byte[]...)
  Attribute(String name, Schema, Collection)
  Attribute(String name, Schema, String...)
  Attribute(String name, String value)
  Attribute(String name, String... values)

Suggestions :
- We want to define an Interface and an Implementation. The selected 
name could be :

 * Attribute for the interface
 * DefaultAttribute for the implementation
 The reason why it's named DefaultAttribute is that it's quite a common 
practice (probably better than BaseAttribute, BasicAttribute or 
AttributeImpl).

- We may define an AbstractAttribute class if needed
- We should also implement Comparable, Iterable (over values), Cloneable 
and externalizable
- We may have a ImmutableAttribute class, a wrapper around a mutable 
Attribute instance
- The class might be schema aware, assuming that we inject the schema 
into it (either via a constructor or via an apply(Schema) method)

- The constructors could be :
  DefaultAttribute()
  DefaultAttribute(String id)
  DefaultAttribute(String id, byte[]... values)
  DefaultAttribute(String id, String... values)
  DefaultAttribute(String id, Value... values)
  DefaultAttribute(AttributeType at)
  DefaultAttribute(AttributeType at, byte[]... values)
  DefaultAttribute(AttributeType at, String... values)
  DefaultAttribute(AttributeType at, Value... values))
  DefaultAttribute(String id, SchemaManager schema)
  DefaultAttribute(String id, SchemaManager schema, byte[]... values)
  DefaultAttribute(String id, SchemaManager schema, String... values)
  DefaultAttribute(String id, SchemaManager schema, Value... values)

Thoughts ?

--

Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Re: [ANNOUNCE] Apache LDAP Client API version 0.1 released

2010-04-21 Thread Emmanuel Lecharny


Hello All

I wish to contribute to this effort of writing LDAP client API's. I am sure
it will be very helpful for consumers of Apache (and maybe other ldap
servers).
Till now my experience has been in writing JNDI code with ApacheDS. I won't
rate myself as a pro but I can work on JNDI and ApacheDS :)

Please let me know if I can help in any way. I searched in archives of this
forum but could not find any pointers as to how to go about it.
   

http://directory.apache.org/community%26resources/contribute.html

This is the starting point :)


   

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Re: [ANNOUNCE] Apache LDAP Client API version 0.1 released

2010-04-21 Thread Emmanuel Lecharny


Hello All

I wish to contribute to this effort of writing LDAP client API's. I am sure
it will be very helpful for consumers of Apache (and maybe other ldap
servers).
Till now my experience has been in writing JNDI code with ApacheDS. I won't
rate myself as a pro but I can work on JNDI and ApacheDS :)

Please let me know if I can help in any way. I searched in archives of this
forum but could not find any pointers as to how to go about it.
   

http://directory.apache.org/community%26resources/contribute.html

This is the starting point :)


   

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Entry and Attribute comparisons

2010-04-27 Thread Emmanuel Lecharny

Hi,

just wondering how deep we should go when implementing the equals() and 
hashcode() methods :
- for an entry, is it enough to check that the DN is equal ? Otherwise, 
we will have to sort all the attributes (based on their OID, I guess), 
then for each Attribute, sort all of their value (using the normalized 
value of course, which means the Attribute is schema aware)...
- for an Attribute, as stated above, we will have somehow to sort the 
normalized values, using the specific syntax for the Attribute, 
otherwise we might not be able to compare two Attributes.


I would rather go for a simpler version of hashcode() and equals() where 
we only compare DN for entries and the attribute ID for Attribute. The 
rational is that we usually never compare entries (or we use a dedicated 
method for that : compare()), and we only need to check if an Attribute 
is stored into an Entry (speaking about the hashcode method). For the 
Attribute equals method, this is slightly different. I'm not sure we 
should compare all the values, but right now, I see no other way to do it...


Thoughts ?

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Re: Problems to do a search

2010-05-12 Thread Emmanuel Lecharny

On 5/12/10 1:07 PM, Juan Luis Hidalgo Vera wrote:

Hi,

We've found a problem when we do a search with a filter with "*" in 
the start or in the end of a expression with wildcards chars like for 
example filter (uid=*se*).


Sounds like a bug !

Can you open a JIRA for that ?

OTOH, you have to know that such a search will be very inefficient, as 
it will resolve to a full scan on the base. Note that it's not a 
workaround, just an information :)



--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Should the BIND throw an Exception ?

2010-06-01 Thread Emmanuel Lecharny

Hi guys,

long time, no see ... Lots of side work going on, but still progressing 
on the API.


I have a question though : should the LdapConnection.bind()operation 
throw an exception, or not ?


Currently we have a version that returns a BindResponse, which is 
convenient but a bit painful if you have got an error, as you have to 
check the response before using the connection.


Wouldn't it be better to just throw an LdapException, containing the 
Bindresponse elements, à la JNDI ?


wdyt ?

--
Regards,
Cordialement,
Emmanuel Lécharny
www.nextury.com




Missing moveAndRename method inLdap Connection

2010-06-12 Thread Emmanuel Lecharny
Hi guys,

the modifyDN operation has been splitted in 3 basic operations in the
LdapConnection class :
- move (the RDN is modified)
- rename (the superior DN is modified)
- modifyDn : any of the two previous operation plus a third one, move and
rename

This is not very convenient, as the third operation is mainly used when one
want to use a ModifyDnRequest object, it was not designed from day one to
cover the 'move and rename' operation.

I will add a moveAndRename operation to have a complete set of methods
covering the ModDN semantic.

-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com


About operation result

2010-07-19 Thread Emmanuel Lecharny

 Hi,

long time, no see :)

I have a proposal about the way we handle the operation results. 
Currently, every operation is returning a Response, and if we want to 
know if the operation has been successful, we have to check the 
LdapResult field. This is not very convenient.


Assuming that when we have issued a synchronous operation, we are 
waiting until we get a response, why can't we have those operations 
throwing a LdapException ?


For async operations, we can also make that the XXXFuture.get() method 
throw the same exception.


thoughts ?

--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: About operation result

2010-07-19 Thread Emmanuel Lecharny

 On 7/19/10 7:02 PM, Matthew Swift wrote:

 Hi Emmanuel,

Long time no hear!

I think this is a good idea. It's what we chose to do in the OpenDS 
SDK and I think that it makes the API much more usable in practice. 
Application code is leaner and less error prone since there is no need 
to check (or forget to check!) the result code after each operation. 
Instead all error handling can be performed in a single catch block at 
the end.


Absolutly. If only you use the API for a moment, it becomes obvious that 
it's the right way to go.


Something else we did was to also create several subclasses of our 
ErrorResultException class in order to make it easier to isolate 
common failure reasons, e.g. connection failure, authn/authz failure, 
referral, timeout, etc:


http://www.opends.org/daily-builds/sdk/latest/OpenDS_SDK/doc/org/opends/sdk/ErrorResultException.html 



I think that this is similar to JNDI. I didn't shoot for a 1:1 mapping 
between result codes and exception types since this would lead to very 
many exception classes which I thought would be a bit excessive. It's 
a trade-off, and I don't know if I set the bar too low or too high. 
The good thing is that it is possible to add more sub-classes later 
without breaking compatibility, so I erred on the low side probably. 
Since all of these exceptions expose the underlying result, it still 
possible to do a catch-all on ErrorResultException and still have 
logic based on the ResultCode.


We have done the same thing a while back : 
http://mail-archives.apache.org/mod_mbox/directory-api/201003.mbox/ajax/%3c4b9a1fe4.4040...@gmail.com%3e


Also note that you will need to make LdapException a sub-class of 
j.u.c.ExecutionException for it to be thrown by Future.get (or make it 
a runtime exception but I think that this is a bad idea). This is a 
bit annoying, but in practice not a big deal (it just looks surprising 
seeing java.util.concurrent in the class hierarchy for a result 
exception).


Another API problem I ran into was what to do with the "checked" 
InterruptedException which can be thrown from blocking operations such 
as Future.get. I could have chosen to catch it and rethrow it as a 
cancelled result exception (or a new exception like 
InterruptedErrorResultException). This would avoid having to 
catch/throw it every time, as this example illustrates:


   Connection connection = ...;
   Entry entry = ...;

   try
   {
  connection.add(entry);
   }
   catch (ErrorResultException e)
   {
  // Handle operation failure.
   }
   catch (InterruptedException e)
   {
  // Grrr... Handle thread interrupt

  // This would not be needed if I caught and re-threw
  // the exception as a sub-type of ErrorResultException.
   }


I played it safe and kept it separate since InterruptedException has a 
very specific contract, so hiding it inside an ErrorResultException 
(or LdapException in your case) might cause it to get overlooked.

+1


--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



DN and valueOf( "" ) method

2010-07-28 Thread Emmanuel Lecharny

 Hi guys,

I was thinking lately about the DN class. I know that OpenDS (and 
probably UnboundId, but not sure) has a DN.valueOf( "" ) factory 
that returns a DN potentially leveraging a cache associated to a 
ThreadLocal.


At first, I thought this was an excellent idea, and started to implement 
such a method in the DN class, but I didn't had time to finalize the 
code, so I let it beside for a while.


Now that I have had a bit of discussion about caching strategy inside a 
server, I'm coming  back to this specific valueOf() method.


I don't think it's such a good idea :
- first, as it's ThreadLocal based, you will have as many cache as you 
have threads processing requests. Not sure it competes with a unique 
cache, not sure either we can't use the memory in a better way...
- second, this is a server side cache : we don'yt need it on the client 
side (or, more specifically, if we need it, then I don't think it 
deserves to be managed by the DN class)


I would rather define a dedicated class, with a static method - a 
factory -, something like :
DnFactory, with a createDn( "" ) method. This factory will handle 
its cache, which will be global.


thoughts ?

--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: DN and valueOf( "" ) method

2010-07-28 Thread Emmanuel Lecharny

 On 7/28/10 11:31 AM, Stefan Seelmann wrote:

I was thinking lately about the DN class. I know that OpenDS (and probably
UnboundId, but not sure) has a DN.valueOf( "" ) factory that returns a
DN potentially leveraging a cache associated to a ThreadLocal.


...

I don't think it's such a good idea :
- first, as it's ThreadLocal based, you will have as many cache as you have
threads processing requests. Not sure it competes with a unique cache, not
sure either we can't use the memory in a better way...

An advantage to use ThreadLocal is that you don't need to synchronize
access to the cache Could be worth to measure the performance
Using ConcurrentHashMap should not be a major performance penalty. I 
mean, it *will* be more costly than not having any synchronization but 
it sounds acceptable.


Another possibility is to use a CopyOnWriteArraySet, but I'm afraid that 
it will crawl if many new DN are added.

difference, I wonder if the OpenDS team did some performance analysis?
They compared the performances they get with a ThreadLocal cache and no 
cache : the gain was sensible (I don't have the number for OpenDS). FYI, 
the DN parsing count for more or less 13% of the whole CPU needed 
internally (network excluded) to process a simple search, and 
normalization cost an extra 10%. There is most certainly a net potential 
gain to implement a DN cache !



--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: DN and valueOf( "" ) method

2010-07-29 Thread Emmanuel Lecharny

 On 7/28/10 10:32 PM, Kiran Ayyagari wrote:

On Wed, Jul 28, 2010 at 4:37 PM, Emmanuel Lecharny  wrote:

  On 7/28/10 11:31 AM, Stefan Seelmann wrote:



I have just committed a DNFactory implementation [1].

Seems good to have.



But the real
issue with this is that
the ApacheDS's DN class is mutable and hence will cause issues[2].

Oh, yeah. DN should be immutable !

A working solution I have is to return a clone of the DN *all* the
time (whether a hit or a miss)
nah way too costly. I would rather forbid any modification on an 
existing DN. Methods adding or removing RDNs from a DN should copy the 
DN before applying the modification. The problem is that iterating throw 
RDNs to create a DN will be costly. Code like :


RDN rdns = new RDN[] { rdn1, rdn2, rdn3, ..., rdn7 };
DN dn = new DN( "ou=system" );

for ( RDN rdn : rdns )
{
dn.add( rdn );
}

will see 7 copies to be created. Simply insane...

May be we should extend the API to have something like a add( DN, RDN ) 
method which allow a modification to be done without copy ?

this is guaranteed to work and am thinking that cloning() is way
faster than the time required for
parsing and normalizing a DN from the beginning. But one penalty we
pay for this solution is that
two instances(of which one is just a clone) will be created for every
DN miss in the cache.
We should think about what it would cost to make DN an immutable class, 
and see what's the impact on the existing cost. I don't think we can 
ignore the problem anymore...



--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: removing unused methods from DN class

2010-08-04 Thread Emmanuel Lecharny

 On 8/4/10 12:04 PM, Kiran Ayyagari wrote:

hello guys,

 When I was working on making DN immutable have come across
some of the methods which are not used anywhere in the server code

1. DN addAll( int posn, Name name ) - except at two places in DNTest
class, which we can remove
This method was created to offer some kind of JNDI conversion tools. I 
think it's useless, as such a JNDI <-> API tool may use a dedicated class.

2. DN add( int pos, RDN newRdn ) - there is another method to add RDN

You are right, it's useless.

3. DN addNormalized( RDN newRdn ) - this functionality is already
present in another method add(RDN)

+1 too. Doom it.

and the serialization functions
1. void readExternal( ObjectInput in )
2. void writeExternal( ObjectOutput out )

this serialization functionality has been moved to DnSerializer class

Doom them.

I propose that we get rid of these methods, thoughts?

No thoughts. Action !

--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



DN API polishing

2010-08-05 Thread Emmanuel Lecharny

 Hi guys,

I'm in the process of polishing the API now that Kiran has included many 
of the missing parts. It raised some questions :


1) there are 3 different methods that give back the list of RDNs :
- getAll()
- iterator()
- getRdns()

One of them is obviously a duplicate. The getAll() is a remaining taint 
of the ancient JNDI API : DN was implementing Name back 5 years ago. I 
don't think we need it anymore.


The iterator() and getRdns() are doing the exact same thing, which is 
different from the getAll() mtehod : there return the inner RDNs in the 
revert order.


For instance, if we have a DN like 'dc=c, dc=b, dc=a', there each of 
those three methods will return RDNs in the following order :

o getRdns() and iterator() :
'dc=c' then 'dc=b' then 'dc=a'
o getAll() will do the opposite :
'dc=a' then 'dc=b' then 'dc=c'

I think that the iterator() method should behave as the getAll() method 
does, and getRdns() should keep the internal order (as it simply return 
the inner field storing the rdns.


2) The JNDI related methods like toName( DN ) and fromName( Name ) have 
been moved to the JndiUtils class. There is no reason to make the DN api 
more heavy than strictly than necessary, IMO


3) There are helper methods like normalize( DN, OIDMap ), normalize( 
String, OIDMap ) or normalize( OIDMap ) that does not belong to the DN 
public API : theyr are used by tests. I think they should also be 
removed from the DN api.


thoughts ?

--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: DN API polishing

2010-08-05 Thread Emmanuel Lecharny

 On 8/5/10 2:56 PM, Francois wrote:

The iterator() and getRdns() are doing the exact same thing, which is
different from the getAll() mtehod : there return the inner RDNs in the
revert order.

For instance, if we have a DN like 'dc=c, dc=b, dc=a', there each of
those three methods will return RDNs in the following order :
o getRdns() and iterator() :
'dc=c' then 'dc=b' then 'dc=a'
o getAll() will do the opposite :
'dc=a' then 'dc=b' then 'dc=c'

I think that the iterator() method should behave as the getAll() method
does, and getRdns() should keep the internal order (as it simply return
the inner field storing the rdns.



I'm not really sure we need the two... A reverse is really easy to do 
if getRdns return a list, and as you said, there is no need to make DN 
api heavier than needed...
well, there are cases you want to 'browse' the DN from right to left 
(for instance, when looking for a specific root) and sometime from left 
to right (when duplicating the internal RDN[] for other purposes), but I 
must admit it's more or less irrelevant for our users.


We may want to modify the getRdns() to return a Collection 
(implementing the Unmodifiable interface), in the same order (ie right 
to left)


About the return type, I would prefer to have a collection I could use 
directly (a List, or even better an immutable list or a list of copies 
of RDN) than an iterator.
Right now, getRdns() return a deep copy of the RDNs (not only you get a 
new List, but all the RDNs are cloned). This is where a Iterator() is 
interesting : you don't have to copy everything.


Plus the RDN should be immutable, alleviating the necessity to clone the 
RDNs...




--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Some thoughts I had under my shower this morning...

2010-08-05 Thread Emmanuel Lecharny

 The best place when it comes to think about the future...

So we will have some potential issues with the LDAP API : as we now have 
a schema Aware, we have to load the schema into a SchemaManager. Right 
now, all the schema is stored into a subproject (shared/ldap-schema) as 
LDIF files. When we try to initialize the schemaManager, we first 
extract the LDIF to the disk.


This is *very* bad ! When one will try to embed the API (in tomcat for 
instance), one will face serious issues as the file system might not be 
writable.


We must fix that so that we can just read the LDIF directly from the 
resources without having to extract the LDIF files to disk. That also 
means we must not try to update the LDIF on disk when modifying the schema.


On solution would be to use the AvlPartition to back the LdifPartition.

I'm not 100% sure that we don't currently have a workaround for this 
problem, but if so, it must be clearly documented. Otherwise, we have to 
provided a way to fix it.


--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: DN API polishing

2010-08-05 Thread Emmanuel Lecharny

 On 8/5/10 8:33 PM, Alex Karasulu wrote:

On Thu, Aug 5, 2010 at 3:56 PM, Francois  wrote:


On 05/08/2010 13:17, Emmanuel Lecharny wrote:


Hi guys,



Hello,

Reply in the text underneath


  I'm in the process of polishing the API now that Kiran has included many

of the missing parts. It raised some questions :

1) there are 3 different methods that give back the list of RDNs :
- getAll()
- iterator()
- getRdns()

One of them is obviously a duplicate. The getAll() is a remaining taint
of the ancient JNDI API : DN was implementing Name back 5 years ago. I
don't think we need it anymore.



Agree with that.



  The iterator() and getRdns() are doing the exact same thing, which is

different from the getAll() mtehod : there return the inner RDNs in the
revert order.

For instance, if we have a DN like 'dc=c, dc=b, dc=a', there each of
those three methods will return RDNs in the following order :
o getRdns() and iterator() :
'dc=c' then 'dc=b' then 'dc=a'
o getAll() will do the opposite :
'dc=a' then 'dc=b' then 'dc=c'

I think that the iterator() method should behave as the getAll() method
does, and getRdns() should keep the internal order (as it simply return
the inner field storing the rdns.



I'm not really sure we need the two... A reverse is really easy to do if
getRdns return a list, and as you said, there is no need to make DN api
heavier than needed...

About the return type, I would prefer to have a collection I could use
directly (a List, or even better an immutable list or a list of copies of
RDN) than an iterator.




+1 on immutable list.


The returned list is now immutable.

All the other modifications have been applied, except the ones on 
normalize() methods.



--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: Some thoughts I had under my shower this morning...

2010-08-05 Thread Emmanuel Lecharny

 On 8/5/10 8:31 PM, Alex Karasulu wrote:

we do have a workaround/fix for this (by setting a special VM option

specifying the location of the
schema directory or the jar file in which schema files are present)



This workaround IMHO is sufficient for embedding into containers. I would
not alter the whole server schema loading behavior just for this very
special case.

Alex

IMO, this is barely acceptable for API 0.2, but has to be fixed for 0.3. 
There is no reason to extract to disk when all the ldifs are available 
in a jar, as it's just a matter of loading them in memory.


It should be a 2 hours work to get the code read the jar and load the 
schema in memory...



--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: Some thoughts I had under my shower this morning...

2010-08-06 Thread Emmanuel Lecharny

 On 8/6/10 10:15 AM, Kiran Ayyagari wrote:



IMO, this is barely acceptable for API 0.2, but has to be fixed for 0.3.
There is no reason to extract to disk when all the ldifs are available in a
jar, as it's just a matter of loading them in memory.

It should be a 2 hours work to get the code read the jar and load the schema
in memory...

it is already possible to do this using JarLdifSchemaLoader , but note
that this will always
contain the bundled default schemas only. A user can only add custom
schema if the
schema directory is present on disk.


Ah, so we are golden.

Is there a place where this is documented (even roughly) ?

I think we have some users facing this issue.

Btw, I don't really care if users can't extend the schema when they 
can't write on disk. But we can discuss about allowing this too.


Thanks Kiran.

--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: Some thoughts I had under my shower this morning...

2010-08-06 Thread Emmanuel Lecharny

 On 8/6/10 10:45 AM, Kiran Ayyagari wrote:

On Fri, Aug 6, 2010 at 2:02 PM, Stefan Seelmann  wrote:

So we will have some potential issues with the LDAP API : as we now have a
schema Aware, we have to load the schema into a SchemaManager. Right now,
all the schema is stored into a subproject (shared/ldap-schema) as LDIF
files. When we try to initialize the schemaManager, we first extract the
LDIF to the disk.

This is *very* bad ! When one will try to embed the API (in tomcat for
instance), one will face serious issues as the file system might not be
writable.

I think that is more worse when one wants to use the API as a client.
IMO the usage of the API must be lightweight. If I startup my program
to just do a search I probably don't want that a schema is loaded at
all, because it is just too heavy. Can we have a DummySchemaManager
implementation, that just does no validation and normalization?

not really, we let schema manager use the in-memory LDIF loader
(JarLdifSchemaLoader) so
no files will be written to disk.


Ok, so we are fine.

However, we should have a mode where the SchemaManager is not even 
loaded. Be it a flag would be good enough.


--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: DN and valueOf( "" ) method

2010-08-09 Thread Emmanuel Lecharny

 On 8/9/10 4:16 PM, Matthew Swift wrote:



On 28/07/10 13:07, Emmanuel Lecharny wrote:

 On 7/28/10 11:31 AM, Stefan Seelmann wrote:
I was thinking lately about the DN class. I know that OpenDS (and 
probably
UnboundId, but not sure) has a DN.valueOf( "" ) factory that 
returns a

DN potentially leveraging a cache associated to a ThreadLocal.


...

I don't think it's such a good idea :
- first, as it's ThreadLocal based, you will have as many cache as 
you have
threads processing requests. Not sure it competes with a unique 
cache, not

sure either we can't use the memory in a better way...

An advantage to use ThreadLocal is that you don't need to synchronize
access to the cache Could be worth to measure the performance
Using ConcurrentHashMap should not be a major performance penalty. I 
mean, it *will* be more costly than not having any synchronization 
but it sounds acceptable.



Unfortunately a CHM won't help either since you need to manage cache 
eviction, assuming that you want the cache to have a finite size. 
LinkedHashMap has an eviction strategy which can be defined by 
overriding the removeEldestEntry method, but unfortunately LHM is not 
thread safe.


Doh !!! I should have thought about it immediately... That's the problem 
when you are pushing random thoughts on the ML instead of *really* 
coding them.



difference, I wonder if the OpenDS team did some performance analysis?



I did some testing some time back and I have forgotten the exact 
figures that I got. I do remember finding a substantial performance 
improvement when parsing DNs when caching is enabled - something like 
30ns with caching vs 300ns without for DNs containing 4 RDN components 
(i.e. about an order of magnitude IIRC).


We implement our DNs using a recursive RDN + parent DN structure so we 
are usually able to fast track the decoding process to just a single 
RDN for DNs having a common ancestor (pretty common).


Our idea was that the first step would be to quickly compute the DN (as 
a String) hashcode, and check if it has already been parsed. If not, 
then we fallback to a plain parsing. But having the low level DN stored 
in the cache is a good idea.


There are definitively many options, we should conduct some perf tests 
based on real world DN to see what's the best.


We opted for the ThreadLocal approach due to the synchronization 
limitations of using a single global cache. However, I have often 
worried about this approach as it will not scale for applications 
having large numbers of threads, resulting in OOM exceptions.
yes, true. But this is also a fast-track solution, bringing immediate 
benefits.


Another approach I have thought about is to use a single global 
two-level cache comprising of a fixed size array of LinkedHashMaps 
(think of it as a Map of Maps) each one having its own 
synchronization. We then distribute the DNs over the LHMs and amortize 
the synchronization costs across multiple locks (in a similar manner 
to CHM).
Another aspect we are interested in is the pining of frequently used DN 
(cn=schema, etc). Not sure it worth the effort though...


This idea needs testing. In particular, we'd need to figure out the 
optimal array size (i.e. number of locks / LHMs). For example, 
distributing the cache over 16 LHMs is not going to help much for 
really big multi-threaded apps containing 16000+ threads (1000 threads 
contending per lock).

But are you going to have 16K threads anyway ?


A major problem with this approach if we choose to use it in the 
OpenDS SDK is that common ancestor DNs (e.g. "dc=com") are going to 
end up in a single LHM so, using our current design (RDN + parent DN), 
all decoding attempts will usually end up contending on the same lock 
anyway :-( So we may need to change our DN implementation to better 
cope with this caching strategy.


We are not alone though: a concurrent Map implementation which can be 
used for caching in a similar manner to LHM is one of the most 
frequently demanded enhancements to the java.util.concurrent library.
There might be some other data structure available, we may need to do 
some research in this area...



--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: DN and valueOf( "" ) method

2010-08-10 Thread Emmanuel Lecharny

 On 8/10/10 9:58 AM, Matthew Swift wrote:

 [...]

But are you going to have 16K threads anyway ?



Perhaps not today, but perhaps tomorrow.


Here, we are entering into the plain IO vs NIO debate.

There is no limit in the number of threads you can start on a JVM except 
the available memory, the JVM configuration (especially the -Xss size. 
It defaults to 1024, which is way to big if you are going to have 100K 
threads...) and obviously the OS you are running on.


There are already very large CMT (core multi-threading) machines in 
the pipeline from various vendors and I have heard and read 
projections of 10K+ thread CMT machines in the next few years. Hence 
the fork/join work going on in JDK7 at the moment and the push for 
closures.


Since many server apps size their thread pools based on the number of 
available processors (core threads on CMT machines) then it is not 
that unlikely in the next few years.


I think that even today some app server environments run with tens of 
thousands of threads.

Most certainly...


Basically, we have no control over how other people use our SDK so, 
while I might not use 16K threads, someone else might :-(
Well, I see no benefit in having 16K threads if the server is NIO based. 
But it might well be a good idea to switch to plain IOs, if we can scale 
to tens of thousands of connected sessions. This is the main issue here, 
compared to a Http server, for instance (where session are short lived). 
But even for a LDAP server, I'm not sure that we really need to deal 
with hundred of thousands opened sessions... Generally speaking, I'm not 
sure it's secure to 'open' the LDAP server to end users, so it's very 
likely that the server will be accessed by an application, which will 
probably not open a session per user, but instead use a pool of sessions 
and reuse it.


This is an interesting debate...

We are using MINA here, which is a NIO based framework, but I foresee a 
version which would be a pure IO framework, using either plain IO or 
NIO. That could help to conduct tests to see what will be the best 
solution (some like Paul Tyma think - and he even demonstrated - that IO 
is 30% fatser than NIO, even with thousands of threads : 
http://mailinator.blogspot.com/2008/02/kill-myth-please-nio-is-not-faster-than.html)







A major problem with this approach if we choose to use it in the 
OpenDS SDK is that common ancestor DNs (e.g. "dc=com") are going to 
end up in a single LHM so, using our current design (RDN + parent 
DN), all decoding attempts will usually end up contending on the 
same lock anyway :-( So we may need to change our DN implementation 
to better cope with this caching strategy.


We are not alone though: a concurrent Map implementation which can 
be used for caching in a similar manner to LHM is one of the most 
frequently demanded enhancements to the java.util.concurrent library.
There might be some other data structure available, we may need to do 
some research in this area...





I did have a poke around some time ago and found a couple. I didn't 
evaluate them though as I seem to remember that they introduced a lot 
of extra "baggage" and I'd like to keep the size of the SDK to a 
minimum (to be honest, I think our OpenDS SDK is already too big).

It would be a pain to carry 1 more Mb of useless libs, true...

--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Null DN constant

2010-09-04 Thread Emmanuel Lecharny

 Hi,

any preference between EMPTY_DN, NULL_DN or ROOT_DN for a null DN constant ?

We currently use EMPTY_DN, but I'm inclined to also create a ROOT_DN 
constant as it's semantically different.


--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: Different layers

2010-09-06 Thread Emmanuel Lecharny

 On 9/6/10 9:30 AM, Pierre-Arnaud Marcelot wrote:

Hi Stefan,

On 4 sept. 2010, at 18:40, Stefan Seelmann wrote:


Hi guys,

in IRC we had the idea to have different levels of abstraction in the
API: A low-level API that represents the LDAP protocol and a more
convenient API for common users that hides the LDAP complexity.

I really like the idea.


Lets start with the search method.

In the low-level API the search method would return a Cursor
and the user has to deal with all possible results (SearchResultDone,
SearchResultEntry, SearchResultReference, IntermediateResponse)

In the convenient API the search method would return a Cursor
and the search method could also deal with referrals and search
continuations (throw as exception or follow transparently if the user
wants to).

Does that make sense? This is just a first thought, we have to figure
if it makes also sense for the other operations too.

+1. Makes totally sense to me.


+1 too. Let's try to do that.


--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: Using LDAPConnection class...

2010-09-06 Thread Emmanuel Lecharny

 On 9/6/10 3:21 PM, Arvind N wrote:

Hi,
Just downloaded the ldap client api version 0.1 and wrote sample program to
connect to a Active Directory seem to hit a weird problem.
The tutorial does not provide much info so thought of checking in the list.
Do let me know if I have got the wrong list.

The piece that is failing is

LdapConnection connection = new LdapConnection(svrIP, 
new Integer(svrPort));
BindRequest request = new BindRequest();
request.setCredentials(password);
request.setName("cn=Arvind N");   
BindResponse resp = connection.bind(request);
LdapResult result = resp.getLdapResult();
System.out.println("the error message is " + 
result.getErrorMessage());   

For this I always get an error message
** the error message is 80090308: LdapErr: DSID-0C090334, comment: 
AcceptSecurityContext error, data 525, vece **
Googled quite a bit to not avail and to dig deeper hit ethereal.
Noticed that in the LDAP protocol extract, the bind request had something like 
this

DN: cn=Arvind N


The user name must be the full DN, ie cn=Arvind N,< ... >, where <...> 
is the DN containing your user.



--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: Using LDAPConnection class...

2010-09-06 Thread Emmanuel Lecharny

 On 9/6/10 4:02 PM, Stefan Seelmann wrote:

AD accepts either
- the full DN, that looks typically like "cn=Arvind
N,cn=Users,dc=MyDomain,dc=com"
- or the samAccountName and the domain in format "Arvind n...@domain"

@Emmanuel, Kiran:
JXplorer makes the same as Apache Directory Studio: It uses JNDI and
JNDI accepts a non-DN as principal. I think we should allow the same
for the new API. WDYT?
I wonder if the LDAP API screams if you use "Arvind n...@domain" as a 
principal. Blind guess : we expect a DN, and we throw an excpetion if 
it's not. We can fix that.


In any case, there is no chance that what Arvin used can work, as it's 
nor a valid DN  (ie a full DN), nor a samAccountName. I guess that 
JExplorer is guessing about the root context to use (ie, it adds 
cn=Users, ... to the given DN).




--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



We should be ready for a release soon

2010-09-06 Thread Emmanuel Lecharny

 Hi guys,

I think we should be able to release LDAP-API-0.2.0 really soon. There 
are a few issues remaining, and once we have fixed those :

- DIRAPI-12 :  add support for LDAPS
- DIRAPI-11 :  add 
support for StartTLS 


Those are the two most important features we would  like to have in 
0.2.0 IMO.


thoughts ?


--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: issues in compiling latest checked out src..

2010-09-07 Thread Emmanuel Lecharny



I am having issues in compiling the latest checked out src from
http://svn.apache.org/repos/asf/directory/clients/ldap/trunk/
Errors mainly crib about .java files missing in
org.apache.directory.shared.ldap.message package... am i missing
something.. ??


Works for me. You may have to rebuild 'shared' before building ldap-API


--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: issues in compiling latest checked out src..

2010-09-08 Thread Emmanuel Lecharny



Well when i do a mvn clean install i get the below exception


[INFO] Surefire report directory:
D:\os\apacheDC\directory-checkstyle\target\surefire-reports
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

Increase the heap size  to -Xmx1024m. It should work.

What JVM are you using ?
Which Maven version ?

--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: issues in compiling latest checked out src..

2010-09-08 Thread Emmanuel Lecharny



For quick success you can try to run
   mvn clean install -DskipTests
That skips the test itself, but installs the required test artifacts.

I think we should create a api-with-dependencies, that includes all
required modules (shared, checkstyle, etc.)
Or we should refactor API and shared so that the API includes shared. I 
see no rationnal now for having a different project for shared and API. 
All in all, shared is a part of API, and as we use API in the server, we 
should merge those two guys...



Another must is to setup a working CI build and to deploy the
artifacts to the snapshot repository. We should also create a CI build
on a Windows machine. Alex granted me access to Hudson, I'll try if it
works and set it up tonight.


We should also provide nightly builds. I have a server on which we can 
store those guys.



--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Twitter for ApacheDS

2010-09-09 Thread Emmanuel Lecharny

 Hi !

just to inform you guys that we have created a twitter account 
(twitter.com/apacheDS) where we will put some relevant infos (well, we 
hope they will be relevant ;).


--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: aci evaluation ...

2010-09-21 Thread Emmanuel Lecharny

 On 9/21/10 12:38 PM, rm wrote:



hi,

i am trying to get ACI information out of an ldap server i am 
connecting to - the gui of the application i am working on should 
change it's state depending on wether or not a user has certain 
permissions (actually, it is as simple as wether or not to display an 
"add" button).


aside from launching an extended operation ... i should be possible to 
get this information, right? so ... i am wondering why it's not 
exposed in any of the APIs i looked at? the apache ldap libs have some 
stuff in the "shared" portion, but i dont think it's a good idea to go 
there ...


being able to get the current state without having to parse all aci 
atts myself seems to be such a straightforward thing - and i can't 
find any hints as to how to do it ... i fear the worst: that i 
completely misunderstood some ldap concepts.


any help? please?
There is nothing such as a common ACI syntax : each LDAP server uses its 
own. So this is quite normal that no API gives you the ACI information...


However, you can grab it, if you know which server you are dealing with, 
but you will probably not be able to do anything with it unless you are 
able to evaluate this ACI.


Sorry for that ...


--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: aci evaluation ...

2010-09-22 Thread Emmanuel Lecharny

 On 9/23/10 12:02 AM, rm wrote:


hi emmanuel,

thanks for your reply ... so, just to clarify ... the only 'standard' 
way to find out wether or not i can perform a certain action is to try 
it? 

Or to analyze the sets of ACI on the client side.
otherwise, i'd be stuck with extended operation 

What for ?
or with parsing serverimplementation- and/or configuration specific 
acl entries?

Absolutely.
but the server should know! 
But the server knows ! The problem is that not only it *knows*, it also 
execute the request.


and it won't tell me? 
Bah, the server is quite secretive :) However, it would be cool to be 
able to ask the server if a specific operation can be executed before 
executing it. It does not exists atm.



that is not a very polite thing to do ...

Even the name itself (LDAP) is a four letters word ;)


--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: [DISCUSSION] General API & SPI Concerns

2011-01-05 Thread Emmanuel Lecharny

On 1/6/11 2:36 AM, Alex Karasulu wrote:

Hi all,

Excuse the cross post but this also has significance to the API list.

Problem


For our benefit and the benefit of our users we need to be uber careful with
changes after a major GA release. We have another thread where it seems
people agree with the Eclipse scheme of versioning and this sounds really
flexible for our needs. We can do a 2.0.0-M1 release at any time without
clamping down on API's. Only when we do a RC do we have to freeze changes to
interfaces.

The debate still remains as to what constitues an interface. Emmanuel seems
to disagree with configuration, schema, and partition db formats as being
interfaces of concern but for the time being we can just discuss those we do
agree on. There's no doubt about APIs and SPIs.


I don't disagree with Schema, but Schema are clearly defined by RFCs, 
there is no possible interpretation about their syntax and definition. 
However, the schema manipulation API is in the scope of this discussion.


Partition and configuration are not part of the Ldap API, thus are 
irrelevant in this discussion about shared refactoring.



Solution


So how do we make this as painless to us and users as much as is possible?
The best way is to keep the surface area of the SPI or API small, create
solid boundaries, and avoid exposing implementation details and
implementation classes.

By reducing the surface area with implementation hiding we can effectively
limit exposure and reduce the probability of needing to make a change that
breaks with our user contract. You might be asking what's a real world
example of this for us in shared?

And incidentally this is one of the things I've been working on in my
branch.


Real World Example in Shared


Let's take the o.a.d.s.ldap.message package as an example. This package
contains classes and interfaces modeling LDAP requests and responses: i.e.
AddRequest, DeleteResponse etc. It's in the shared-ldap module.

In this package, in addition to request response interfaces, we're exposing
implementation classes for them. The implementation classes, in turn have
dependencies on o.a.d.s.ldap.codec.* packages.
Not any more, I hope. We did a big refactoring last september in order 
to remove this coupling. Of course, we may have some remaining 
dependencies, but this is more or less not intentional.



  This is because some
implementation classes depend on codec functionality which is an
implementation detail.


Not true anymore (or is it?).

This might be due to eager reuse or the addition of
utility methods into codec classes for convenience. Some of these
dependencies can be removed by breaking out non-implementation specific
methods and constants in codec classes into utility methods outside of the
package or the module all together. Furthermore the codec implementation
that handles [de]marshaling has to access package friendly (non-API) methods
on implementation classes while encoding.

Not sure that I get what you mean here. Can you be a bit more explicit ?

In the end, dependency upon further transitive dependencies are making us
expose almost all implementation classes in shared, and most can easily be
decoupled and hidden. It's effectively making everything in shared come
together in one big heap exposing way more than we want to.
It's quite impossible in Java to 'hide' all the classes that a user 
should not manipulate. Unless you use package protected classes, and it 
quickly has a limit, I would rather think in term of 'exposed' (ie 
documented) API. That this documented API is gathered in one separate 
module for convenience is another aspect, but the user will still have 
to depend on all the other modules.


So all in all, should we define a module (a maven module) containing the 
public API and the associated implementation ? Probably (But this is not 
an absolute necessity). I guess this is what you have in mind, so let's 
see what's the proposal is...


LDAP Client API


Everyone agrees that this API is very important to get right with a 1.0.
Right now this API pulls in several public interfaces directly from shared.
Those interfaces also pull in some implementation classes. The logical API
extends into shared this way. Effectively the majority of shared is exposed
by the client API. The client API does not end at it's jar boundary.

All this exposure increases the chances of API change when all
implementation details are wide open and part of the client API.  And this
is what I'm trying to limit. There are ways we can decouple these
dependencies very nicely with a mixed bag of refactoring techniques while
breaking up shared-ldap into lesser more coherent modules. The idea is to
expose the bare minimum of only what we need to expose. Yes the shared code
has become very stable over time but the most stability is in the interfaces
and if we only expose these instead of implementation 

Re: [DISCUSSION] General API & SPI Concerns

2011-01-06 Thread Emmanuel Lecharny

On 1/6/11 2:58 PM, Alex Karasulu wrote:

However, the schema manipulation API is in the scope of this discussion.



This is part of the LDAP API and is as critical as Dn, or Entry since it's
tied together.
Damn, I overlooked this part. yes, you are totally right here, as soon 
as the LdapAPI provide Schema aware objects...

Partition and configuration are not part of the Ldap API, thus are
irrelevant in this discussion about shared refactoring.



Right this has nothing to do with shared APIs but is relavent to the server.
The same policies in API maintenance in shared will have to be applied to
the server.
yes, +1. I just want to discuss the server API in the server ML, to 
avoid confusion.


This is not to blame anyone. I am pointing out the problem, and pointing out
a solution to it so we're not screwed by it. The web of dependencies in
shared will f**k us down the line if we don't nix em now.


I'm wondering what would be the best way to get rid of those coupling... 
May be creating many maven modules (one per package) then we will 
immediately see the invalid coupling ? Or is there any tool we can use 
to detect the bad coupling ?


I must admit I have not investigated this area yet...

implementation classes depend on codec functionality which is an
implementation detail.


Not true anymore (or is it?).



Yeah there's some residual dependencies but not a big deal to fix. Trivial
stuff.

We then have to fix them.


The work needed here is a joke really. The big issue with it is the impact
the changes in shared have all over the place in Studio and ApacheDS and the
fact that we're better off waiting for AP work to complete to merge.
Absolutely. I know that I'm a bottleneck here, but OTOH, there is little 
I can do to move faster :/



  This might be due to eager reuse or the addition of

utility methods into codec classes for convenience. Some of these
dependencies can be removed by breaking out non-implementation specific
methods and constants in codec classes into utility methods outside of the
package or the module all together. Furthermore the codec implementation
that handles [de]marshaling has to access package friendly (non-API)
methods
on implementation classes while encoding.


Not sure that I get what you mean here. Can you be a bit more explicit ?


LdapEncoder accesses package friendly methods inside most message Impl
clases to encode them. This also pulls into message dependencies from codec
which can be hidden. But these are really easy to fix. We just need to know
that the situation is there and get rid of it.

Get it now.

Btw, I still have some issues with the codec classes 
(LdapEncoder/LdapDecoder). They could be simplified, as we still live 
with some mechanisms used years ago. The Client-API codec is way simpler.


We can discuss this point in a separate thread.


  In the end, dependency upon further transitive dependencies are making us

expose almost all implementation classes in shared, and most can easily be
decoupled and hidden. It's effectively making everything in shared come
together in one big heap exposing way more than we want to.


It's quite impossible in Java to 'hide' all the classes that a user should
not manipulate. Unless you use package protected classes, and it quickly has
a limit, I would rather think in term of 'exposed' (ie documented) API.


OSGi bundles really helps in this respect. It fills in where Java left off.

OSGi makes it so the (bundle) packaging coincides with module boundaries. In
Java this is loose and there's leakage all over, as you say, it's very hard
to hide all implementation classes.


True. I ruled out OSGi, but that may help a lot.

That this documented API is gathered in one separate module for convenience
is another aspect, but the user will still have to depend on all the other
modules.



Certainly, you're right, dependencies will still exist. A codec will be
depended upon for it's functionality even if we do hide the implementation
details under the hood.

The value add here is not from avoiding a dependency. It's from not exposing
more than we have to and being able to hide the implementation. This way we
can change the implementation at will across point releases without having
to bump up to a major revision.
what is important here, as you say, is to avoid exposing things that the 
user does not have to manipulate. It's noise to him.





LDAP Client API


Everyone agrees that this API is very important to get right with a 1.0.
Right now this API pulls in several public interfaces directly from
shared.
Those interfaces also pull in some implementation classes. The logical API
extends into shared this way. Effectively the majority of shared is
exposed
by the client API. The client API does not end at it's jar boundary.

All this exposure increases the chances of API change when all
implementation details are wide open and part of the client API.  And this
is what I'm trying to limit. There are ways we c

Re: [Shared] API Design Questionnaire #1

2011-01-29 Thread Emmanuel Lecharny

On 1/28/11 5:58 PM, Alex Karasulu wrote:

Hi community,

Now that we're coming close to finishing up the shared refactoring we have
to make some choices. Not all these choices have major impacts but some
might. In the past we could do what we liked and change our minds etc. Now
with a 1.0 of the shared libraries as the future mother of all Java LDAP
APIs we're going to have to live with our choices.

To opine, just place an 'X' in an option [  ] box.


(1) ModifyRequest has a bunch of methods that were recently added to perform
the same operations that you use the Modification interface for. This is
redundant in my opinion and adds more unnecessary surface area. We don't
need it and don't need an optional path to do the same thing confusing our
users.  I suggest removing them.

[  ] Yes - get rid of extra optional methods
[X] No  - keep the extra optional methods
[  ] --- - I don't care about this stuff


But I would change their names. They are confusing. Be aware that I'm 
not 100% convinced that those methods are *really* important, so I may 
change my opinion later (to 'remove them')

(2) Interfaces verses simple/basic classes implementing them have been
something I've swayed back and forth on. Here are the options but note I am
just using AddRequest as an example.

[X] - (a)
 interface = *I*AddRequest
 simple API exposed implementation = AddRequest
 not so simple internal use implementation = AddRequest*Decoder*
[X] - (c)
 interface = AddRequest
 simple API exposed implementation = AddRequest*Impl*
 not so simple internal use implementation = AddRequest*Decoder*

We're applying option 'C' right now. I'm torn but think A might suite us
better for the long term, and for any situation. You also know what's an
interface and what's not although the IDE automatically shows you this stuff
on the package/class browser.
I do think that *I* is better for users, as it gives them a clue about 
the fact that's is an interface.


In any case, if we pick this option, we have to do it for all the code base.

Right now, I suggest we stay on (c)


(3) JNDI remnants are somewhat still present even if we've gotten rid of
most of them. In the model interfaces for Control, ExtendedRequest, and
ExtendedResponse (IntermediateResponse as well but this has nothing to do
with JNDI) we have exposed access to ASN.1 encoded data. I think this is a
big mistake to do in the public API.


Never had the energy to get rid of those. One of the reasons was that we 
used those classes inside the server (in the SP part).


But, yes, we must get rid of them. There is an existing JIRA for such an 
action, btw.

Controls and extended operation interfaces should simply expose
parameters/properties leaving the rest up to the CODEC to handle. There
should be no need to get or set the entire ASN.1 blob for the control or
extended operation's request response pair. What good does it do anyway?
It's just opening the door for users to incorrectly alter properly encoded
ASN.1 data causing problems. I think the getValue() setValue() methods
remained after we ran screaming away from JNDI. But it seems these
interfaces remained and now they're a liability. Where manipulation of the
binary ASN.1 data is needed we can leave this up to the CODEC under a
decorator to do.

I recommend removing these, what do you think?

[X] Yes - Remove them, they are more bad then good
[  ] No  - Don't remove them, I like using em
[  ] --- - I don't give a rat's a**



--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: [DISCUSS] Close api@ list

2011-01-29 Thread Emmanuel Lecharny

On 1/29/11 11:26 PM, Stefan Seelmann wrote:

Hi guys,

I'd like to propose (again) to close this api@ list.

Was it already proposed? I don't remember...

It was created to work together with the OpenDS guys on a new API. But
unfortunately due to Oracle's acquisition of Sun this doesn't happen
any more. Not sure if there will be a revival with ForgeRock/OpenDJ
folks?

No idea.

I think it is best to continue discussion about the API design at the
dev@ list for several reasons:
- the aim to create a vendor-neutral API failed, we just work on an
Apache LDAP API
- IMHO the API is/becomes a first-class citizen like ApacheDS or Studio
- currently the API discussion is splitted, some discussion happens
here, other discussions happen on the dev@ list


I think you are right. A also think that once the API is out, we may not 
get that many mails about it. Plus we have a risk of having questions on 
the dev and api mailing list, with some responses sant to the wrong list.

Is anyone subscribed and still interested on this api@ list but not on
the dev@ list and would appreciate to continue API dicussions here?

WDYT?


+1.Or at list, make it dormant. We can rescucitate it later, if needed.


--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: [Shared] API Design Questionnaire #1

2011-01-29 Thread Emmanuel Lecharny

On 1/29/11 10:38 PM, Stefan Seelmann wrote:



[X] - (c)
interface = AddRequest
simple API exposed implementation = AddRequest*Impl*
not so simple internal use implementation = AddRequest*Decoder*
We're applying option 'C' right now. I'm torn but think A might suite us
better for the long term, and for any situation. You also know what's an
interface and what's not although the IDE automatically shows you this stuff
on the package/class browser.

This is my opinion for a low-level API, which 1:1 maps LDAP
terminology to the Java API. I think we should additional have a
simplified API where the user don't need to deal with request and
response objects at all.

BTW: We have this discussion again and again ;-) We really need to
decide a consistent naming.


I think we already discussed it more than once, and we all agreed on 
this convention.


I'm not sure we want to rehash this again every 2 years :/

--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: [Shared] API Design Questionnaire #1

2011-01-30 Thread Emmanuel Lecharny

On 1/30/11 7:07 PM, Alex Karasulu wrote:

On Sun, Jan 30, 2011 at 7:29 PM, Stefan Seelmannwrote:


On Sun, Jan 30, 2011 at 5:11 PM, Alex Karasulu
wrote:

On Sun, Jan 30, 2011 at 3:17 AM, Emmanuel Lecharny
On 1/29/11 10:38 PM, Stefan Seelmann wrote:


  [X] - (c)

interface = AddRequest
simple API exposed implementation =

AddRequest*Impl*

not so simple internal use implementation =
AddRequest*Decoder*
We're applying option 'C' right now. I'm torn but think A might suite

us

better for the long term, and for any situation. You also know what's

an

interface and what's not although the IDE automatically shows you this
stuff
on the package/class browser.


This is my opinion for a low-level API, which 1:1 maps LDAP
terminology to the Java API. I think we should additional have a
simplified API where the user don't need to deal with request and
response objects at all.

BTW: We have this discussion again and again ;-) We really need to
decide a consistent naming.


I think we already discussed it more than once, and we all agreed on

this

convention.

I'm not sure we want to rehash this again every 2 years :/



When there's a push to release a 1.0 of an API, we need to make the API
consistent. I can do this myself but the community way is to have a
discussion. If  you do not want to discuss this feel free not to
participate, or say you don't care.

I don't see that anyone said that the API development should not be
community driven.


I did not suggest anyone said that. If you read above I am saying I have no
choice but to post and share with the community rather than do it myself.


We have to be careful in our phrasing. Or we should be careful in the 
way we understand things.


The *I* notation in shared has been added temporarily in order to ease 
the refactoring, and should be removed in trunk.


Again, injecting them in trunk was probably a wrong move, and should 
have been done in a branch. We all know that...


Ok, assuming that this was just a misunderstanding, I guess we can move on.


--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



LDAPCon 2011 : Call for paper is new open

2011-04-08 Thread Emmanuel Lecharny


   LDAPCon 2011


   The third International Conference on LDAP (LDAPCon) will take
   place in
   October 10 – 11 in Heidelberg, Germany.

The International Conference on LDAP is a technical forum for IT 
professionals interested in LDAP and related topics like directory 
servers, directory management applications, directory integration, 
identity and access management, and meta directories.



It focuses on implementation and integration of LDAP servers and 
LDAP-enabled client applications. The event will bring together vendors, 
developers, active and prospective LDAP practitioners to share their 
experiences about deployment strategies, service operations, 
interoperability, discuss LDAP usage in new projects and learn about 
upcoming trends and developments.



The conference language is english.

The web site is :http://www.daasi.de/ldapcon2011/

CFP : http://www.daasi.de/ldapcon2011/index.php?site=cfp


--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: LdapConnection threadsafe?

2011-04-10 Thread Emmanuel Lecharny

On 4/11/11 8:26 AM, Luis Pérez wrote:

Hi,

Is the LdapConnection object threadsafe?
It's supposed to be. You should be able to send a SearchRequest and an 
AbandonRequest through the same connection, and see your searchRequest 
abandonned (if it's a long one, of course.



Can I perform two concurrent
searches on the same LdapConnection?
Yes. But I must admit we never tested this case. We will add some test, 
that's a very valid question. I'll be back to you later today when I 
have tested this point.



--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: Implementing Ldap Persistent search using apache directory api

2011-04-17 Thread Emmanuel Lecharny

On 4/17/11 6:35 PM, Narendra Kadali wrote:

Hi All,

I am new to this apache directory api and there is no documentation available.

The documentation effort is currently being conducted.


I need to implement directory persistance search using this api.

This is pretty simple.


Can any one give me sample code for implementing my scenario or any refrences 
for doing this.
Persistent search is just a normal search except that you pass the 
PersistentSearch control with the search request.
The search operation is explained on 
http://directory.apache.org/api/tutorials.html.


Adding a control can be done following this sample :

Control psearchControl = new PersistentSearchImpl();
SearchRequest sr = new SearchRequestImpl();
sr.setBase( new Dn( "ou=system" ) );
sr.setFilter( "(objectclass=*" );
sr.setScope( SearchScope.SUBTREE );
sr.addControl( psearchControl );

SearchCursor results = connection.search( sr );

then process the entries.

You will also have to set the connection timeout to 0, otherwise it 
won't last longer than 30 seconds.


Hope it helps.

--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: Implementing Ldap Persistent search using apache directory api

2011-04-18 Thread Emmanuel Lecharny

On 4/18/11 9:13 AM, Narendra Kadali wrote:

Hi Cordialement,

Thanks for your reply.

I need to perform this persistent search operation on Active Directory . For 
Active Directory OID for persistent search is 1.2.840.113556.1.4.528 which is 
diffrent from standard oid 2.16.840.1.113730.3.4. So how can i change defined 
PersistentSearchControl  OId to this new OID.


You can't. The OID is not a variable, it's used to determinate exactly 
the Control you are using.


What you can do is to use an instance of the OpaqueControl class :

 Control psearchControl = new OpaqueControl( "1.2.840.113556.1.4.528" );
 SearchRequest sr = new SearchRequestImpl();
 sr.setBase( new Dn( "ou=system" ) );
 sr.setFilter( "(objectclass=*" );
 sr.setScope( SearchScope.SUBTREE );
 sr.addControl( psearchControl );

It should work.

You can also ask for the addition of the ActiveDirectory PersistentSearch 
control by creating a JIRA.

PS: And again, we all thanks a lot the f*ckers at M$ who decided to use a 
different OID than the standard one ... :/


--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



[ANNOUNCE] Apache LDAP API 1.0.0-M3 has been released !

2011-04-27 Thread Emmanuel Lecharny
The Apache Directory team is proud to announce the availability of the 
1.0.0-M3 version of the Apache Directory LDAP API.


The Apache LDAP client API is an ongoingeffort to provide an enhanced 
LDAP API, as a replacement for JNDI and the existing LDAP API (jLdap and 
Mozilla LDAP API).


This is a schema aware API, with some convenient ways to access a LDAP 
server. This API is not only targetting the Apache Directory Server, but 
should work pristine with any LDAP server.


It's also an extensible API : new Controls, schema elements and network 
layer could be added or used in the near future. *It includes an OSGi 
based plugin framework for extending the API.*


This is the first official milestone (two others have already been 
released but not announced), we will release few more milestone versions 
before a release candidate,  but the current version has already been 
validated in Directory Studio and in the Apache Directory Server. Its 
documentation is currently under construction.


Feel free to experiment, we highly appreciate your feedback !

Web site : http://directory.apache.org/api/
Download : http://directory.apache.org/api/downloads.html
User Guide : http://directory.apache.org/api/user-guide.html

--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: LdapCodecService and Felix

2011-05-07 Thread Emmanuel Lecharny

On 5/7/11 5:57 AM, Daniel Fisher wrote:

The LdapNetworkConnection class gets a singleton instance of
StandaloneLdapCodecService which starts Felix. I don't see any code
that shuts down that instance and it appears to block until that
happens. The following code illustrates what I'm seeing: (using
1.0.0-M3)

import org.apache.directory.ldap.client.api.*;
import org.apache.directory.shared.ldap.codec.standalone.*;

public class Test
{
   public static void main(String[] args) throws Exception
   {
 LdapNetworkConnection lc = new LdapNetworkConnection();
 // uncomment to fix
 //StandaloneLdapCodecService cs =
 //  (StandaloneLdapCodecService) lc.getCodecService();
 //cs.shutdown();
   }
}

As is, the main method will block forever. If you uncomment the call
to shutdown(), main exits cleanly.

Are clients responsible for managing the LdapCodecService, have I miss
configured something, or is this a bug?


Definitively a bug.

Can you fill a jIRA? This will be fixed in the next release.

Thanks !

--Daniel Fisher




--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: new LdapNetworkConnection throws Illegal Argument exception

2011-12-05 Thread Emmanuel Lecharny

On 12/5/11 7:40 AM, Christoph Czurda wrote:

Hi!

I have tried to connect to ApacheDS server using LDAP api. However I got
the following error:

Exception in thread "pool-16-thread-1"
java.lang.IllegalArgumentException: factory
at
org.apache.mina.filter.codec.ProtocolCodecFilter.(ProtocolCodecFilter.java:73)
at
org.apache.directory.ldap.client.api.LdapNetworkConnection.(LdapNetworkConnection.java:229)


The exception is thrown here:

LdapConnection connection = new LdapNetworkConnection( "localhost", 10389 );

What could be the problem?


It's a bit complicated. You need to have a ProtocolCodecFactory loaded 
before being able to instanciate the ProtocolCodecFilter class, and that 
means you must  include the 
org.apache.directory.shared.ldap.codec.protocol.mina.LdapProtocolCodecFactory 
class into your environment. This class is loaded using reflection, 
unless you specify another one, and it's present in the 
shared-ldap-net-mina jar.


Include it into your loaded bundles, and you should be fine (assuming 
ypu also have the bundles this bundle depends on present too.)



--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: connection.getSchemaManager() returns null

2011-12-10 Thread Emmanuel Lecharny

On 12/10/11 6:25 PM, Christoph Czurda wrote:

Hello,

Why does connection.getSchemaManager() return null? My connection is
connected and bound.


If no schema is loaded, the schemaManager will be null.

This version of the API currently does not read the schema from the 
remote server other than Apache DS.


Right now, we just support the loading of a local schema, in a LDIF 
format. i'm not quite sure that it's what you want though.


The code that loads the schema from the remote server is still brittle, 
and need to be tested against many different servers, but we can 
probably write a preliminary version for a server like OpenLDAP in a 
matter of a couple of days.


I would suggest that you create a JIRA for that.
--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: connection.getSchemaManager() returns null

2011-12-10 Thread Emmanuel Lecharny

On 12/10/11 7:25 PM, Christoph Czurda wrote:


On 12/10/2011 06:29 PM, Kiran Ayyagari wrote:

On Sat, Dec 10, 2011 at 12:25 PM, Christoph Czurda
  wrote:

Hello,

Why does connection.getSchemaManager() return null? My connection is
connected and bound.


you have to call connection.loadSchema() first.

I did that and then it worked, thank you.

I want to add a custom ObjectClass which is why I need the SchemaManager.

if you want to add new entries based on this objectclass then you
should add that in the server

Using ApacheDS I guess I do this by placing an ldif file containing my
object class somewhere into instances/default/partitions/schema ? Could
you point out to me how to find the exact location?

depends on the schema you are updating.

Let's say you are updating cn=other, and that you are adding an 
ObjectClass. You have to add the ObjectClass ldif file in :


instances/default/partitions/schema/ou=schema/cn=other/ou=objectclasses

If this ou=objectclasses directory does not exist, create it.

The ObjectClass must be a ldif file which name is m-oid=.ldif

You can create this ldif file using Apache directory studio.


You also have to restart the server.

Note that you can also inject your new ObjectClass into the server using the 
same LDIF file, it will be available directly.



--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: startTLS hostname verification

2012-01-21 Thread Emmanuel Lecharny

On 1/20/12 9:14 PM, Daniel Fisher wrote:

Looking over the API I don't see an obvious way to perform hostname
verification after the SSL handshake. Is this currently possible?


I have to  check that. It should be possible, as it's a part of the 
underlying MINA layer, but we may not expose this feature.


Can you feel a JIRA with your request so that it does not get buried in 
the stack of forgotten 'todo' tasks ?


Thanks !


--
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com



Re: QName class in xpp dependency causes linkage problems in Weblogic

2014-08-23 Thread Emmanuel Lecharny
If you are not going tu use DSML, yiu can simply remive the dependency on
xpp.
Le 23 août 2014 09:56, "Barney"  a écrit :

> Hi,
>
> When I include the directory api in my project via Maven, it pulls in a
> dependency for xpp3-1.1.4c.jar.
>
> 
>   org.apache.directory.api
>   api-all
>   1.0.0-M24
> 
>
> This can cause problems (for me on Weblogic server) as the xpp3 library
> includes a version of the javax.xml.namespace.QName class, which can then
> cause linkage errors when using the prefer-web-inf-classes setting to alter
> the classpath loading.
>
> My question is simply: is this full dependency on xpp3 still required, or
> is a dependency on xpp3_min sufficient? It definitely works for me - by
> changing my pom.xml to the following:
>
> 
>   org.apache.directory.api
>   api-all
>   1.0.0-M24
>   
> 
>   xpp3
>   xpp3
> 
>   
> 
> 
>   xpp3
>   xpp3_min
>   1.1.4c
> 
>
> My classloading issues are fixed. I'm obviously not covering all the full
> tests here though, so there may be stuff that would no longer work with
> this.
>
> This workaround is fine for my use-case, but it seems that if the full
> dependency is not required it would be good to replace it with the minimal
> one.
>
> Cheers,
>
> Barney
>
>


Greek greetings

2016-04-25 Thread Emmanuel Lecharny
Hi fellow symasers!

We are enjoying the sun, the gorgious landscapes and the Ouzo of course.
Can't wait to be back (not)...

Καλι σπερα!


-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com


  1   2   >