View Javadoc
1   /*
2    * The contents of this file are subject to the terms of the Common Development and
3    * Distribution License (the License). You may not use this file except in compliance with the
4    * License.
5    *
6    * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
7    * specific language governing permission and limitations under the License.
8    *
9    * When distributing Covered Software, include this CDDL Header Notice in each file and include
10   * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
11   * Header, with the fields enclosed by brackets [] replaced by your own identifying
12   * information: "Portions Copyright [year] [name of copyright owner]".
13   *
14   * Copyright 2015 ForgeRock AS.
15   */
16  
17  package org.forgerock.opendj.examples;
18  
19  import static org.forgerock.util.Utils.closeSilently;
20  import org.forgerock.opendj.ldap.Connection;
21  import org.forgerock.opendj.ldap.LDAPConnectionFactory;
22  import org.forgerock.opendj.ldap.LdapException;
23  import org.forgerock.opendj.ldap.ResultCode;
24  import org.forgerock.opendj.ldap.requests.Requests;
25  import org.forgerock.opendj.ldap.responses.BindResult;
26  import org.forgerock.opendj.ldap.responses.Result;
27  import org.forgerock.util.AsyncFunction;
28  import org.forgerock.util.promise.ExceptionHandler;
29  import org.forgerock.util.promise.Promise;
30  import org.forgerock.util.promise.ResultHandler;
31  
32  import java.io.BufferedReader;
33  import java.io.FileInputStream;
34  import java.io.FileNotFoundException;
35  import java.io.IOException;
36  import java.io.InputStream;
37  import java.io.InputStreamReader;
38  import java.util.ArrayList;
39  import java.util.List;
40  import java.util.concurrent.CountDownLatch;
41  
42  /**
43   * An example client application which applies update operations to a directory server
44   * using the asynchronous APIs.
45   * The update operations are read from an LDIF file, or stdin if no filename is provided.
46   * This example takes the following command line parameters,
47   * reading from stdin if no LDIF file is provided:
48   *
49   * <pre>
50   *  {@code <host> <port> <username> <password> [<ldifFile>]}
51   * </pre>
52   */
53  public final class ModifyAsync {
54      /** Connection to the LDAP server. */
55      private static Connection connection;
56      /** Result for the modify operation. */
57      private static int resultCode;
58      /** Count down latch to wait for modify operation to complete. */
59      private static final CountDownLatch COMPLETION_LATCH = new CountDownLatch(1);
60  
61      /**
62       * Main method.
63       *
64       * @param args
65       *            The command line arguments: host, port, username, password,
66       *            LDIF file name containing the update operations.
67       *            Stdin is used if no LDIF file name is provided.
68       */
69      public static void main(final String[] args) {
70          if (args.length < 4 || args.length > 5) {
71              System.err.println("Usage: host port username password [ldifFileName]");
72              System.exit(1);
73          }
74  
75          // Parse command line arguments.
76          final String hostName = args[0];
77          final int port = Integer.parseInt(args[1]);
78          final String userName = args[2];
79          final char[] password = args[3].toCharArray();
80  
81          // Create the LDIF reader using either the named file, if provided, or stdin.
82          InputStream ldif;
83          if (args.length > 4) {
84              try {
85                  ldif = new FileInputStream(args[4]);
86              } catch (final FileNotFoundException e) {
87                  System.err.println(e.getMessage());
88                  System.exit(ResultCode.CLIENT_SIDE_PARAM_ERROR.intValue());
89                  return;
90              }
91          } else {
92              ldif = System.in;
93          }
94          final String[] ldifLines = getInputLines(ldif);
95  
96          // Connect to the server, bind, and request the modifications.
97          new LDAPConnectionFactory(hostName, port)
98                  .getConnectionAsync()
99                  .thenAsync(new AsyncFunction<Connection, BindResult, LdapException>() {
100                     @Override
101                     public Promise<BindResult, LdapException> apply(Connection connection)
102                             throws LdapException {
103                         ModifyAsync.connection = connection;
104                         return connection.bindAsync(
105                                 Requests.newSimpleBindRequest(userName, password));
106                     }
107                 })
108                 .thenAsync(new AsyncFunction<BindResult, Result, LdapException>() {
109                     @Override
110                     public Promise<Result, LdapException> apply(BindResult bindResult)
111                             throws LdapException {
112                         return connection.modifyAsync(
113                                 Requests.newModifyRequest(ldifLines));
114                     }
115                 })
116                 .thenOnResult(new ResultHandler<Result>() {
117                     @Override
118                     public void handleResult(Result result) {
119                         resultCode = result.getResultCode().intValue();
120                         COMPLETION_LATCH.countDown();
121                     }
122                 })
123                 .thenOnException(new ExceptionHandler<LdapException>() {
124                     @Override
125                     public void handleException(LdapException e) {
126                         System.err.println(e.getMessage());
127                         resultCode = e.getResult().getResultCode().intValue();
128                         COMPLETION_LATCH.countDown();
129                     }
130                 });
131 
132         try {
133             COMPLETION_LATCH.await();
134         } catch (InterruptedException e) {
135             System.err.println(e.getMessage());
136             System.exit(ResultCode.CLIENT_SIDE_USER_CANCELLED.intValue());
137             return;
138         }
139 
140         closeSilently(connection);
141         System.exit(resultCode);
142     }
143 
144     /**
145      * Returns the lines from the input stream.
146      * @param in    The input stream.
147      * @return The lines from the input stream.
148      */
149     private static String[] getInputLines(final InputStream in) {
150         String line;
151         final BufferedReader reader = new BufferedReader(new InputStreamReader(in));
152         final List<String> lines = new ArrayList<>();
153         try {
154             while ((line = reader.readLine()) != null) {
155                 lines.add(line);
156             }
157         } catch (IOException e) {
158             System.err.println(e.getMessage());
159             System.exit(ResultCode.CLIENT_SIDE_LOCAL_ERROR.intValue());
160         }
161         return lines.toArray(new String[lines.size()]);
162     }
163 
164     private ModifyAsync() {
165         // Not used.
166     }
167 }