001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 *
019 */
020package org.apache.directory.server.ldap.handlers.extended;
021
022
023import java.io.Serializable;
024import java.util.ArrayList;
025import java.util.Collections;
026import java.util.HashSet;
027import java.util.List;
028import java.util.Set;
029
030import org.apache.commons.lang3.SerializationUtils;
031import org.apache.directory.api.ldap.codec.api.LdapApiService;
032import org.apache.directory.api.ldap.extras.extended.ads_impl.storedProcedure.StoredProcedureFactory;
033import org.apache.directory.api.ldap.extras.extended.storedProcedure.StoredProcedureRequest;
034import org.apache.directory.api.ldap.extras.extended.storedProcedure.StoredProcedureResponse;
035import org.apache.directory.api.ldap.model.entry.Entry;
036import org.apache.directory.api.ldap.model.name.Dn;
037import org.apache.directory.api.ldap.sp.LdapContextParameter;
038import org.apache.directory.server.core.api.sp.StoredProcEngine;
039import org.apache.directory.server.core.api.sp.StoredProcEngineConfig;
040import org.apache.directory.server.core.api.sp.StoredProcExecutionManager;
041import org.apache.directory.server.core.api.sp.java.JavaStoredProcEngineConfig;
042import org.apache.directory.server.ldap.ExtendedOperationHandler;
043import org.apache.directory.server.ldap.LdapServer;
044import org.apache.directory.server.ldap.LdapSession;
045
046
047/**
048 * A Handler for the StoredProcedure extended operation
049 *
050 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
051 */
052public class StoredProcedureExtendedOperationHandler implements
053    ExtendedOperationHandler<StoredProcedureRequest, StoredProcedureResponse>
054{
055    private StoredProcExecutionManager manager;
056    private static final Object[] EMPTY_CLASS_ARRAY = new Object[0];
057
058
059    public StoredProcedureExtendedOperationHandler()
060    {
061        super();
062        //StoredProcEngineConfig javaxScriptSPEngineConfig = new JavaxStoredProcEngineConfig();
063        StoredProcEngineConfig javaSPEngineConfig = new JavaStoredProcEngineConfig();
064        List<StoredProcEngineConfig> spEngineConfigs = new ArrayList<>();
065        //spEngineConfigs.add( javaxScriptSPEngineConfig );
066        spEngineConfigs.add( javaSPEngineConfig );
067        String spContainer = "ou=Stored Procedures,ou=system";
068        this.manager = new StoredProcExecutionManager( spContainer, spEngineConfigs );
069    }
070
071
072    @Override
073    public void handleExtendedOperation( LdapSession session, StoredProcedureRequest req ) throws Exception
074    {
075        String procedure = req.getProcedureSpecification();
076        Entry spUnit = manager.findStoredProcUnit( session.getCoreSession(), procedure );
077        StoredProcEngine engine = manager.getStoredProcEngineInstance( spUnit );
078
079        List<Object> valueList = new ArrayList<>( req.size() );
080
081        for ( int ii = 0; ii < req.size(); ii++ )
082        {
083            byte[] serializedValue = ( byte[] ) req.getParameterValue( ii );
084            Object value = SerializationUtils.deserialize( serializedValue );
085
086            if ( value.getClass().equals( LdapContextParameter.class ) )
087            {
088                String paramCtx = ( ( LdapContextParameter ) value ).getValue();
089                value = session.getCoreSession().lookup( new Dn( paramCtx ) );
090            }
091
092            valueList.add( value );
093        }
094
095        Object[] values = valueList.toArray( EMPTY_CLASS_ARRAY );
096        Object response = engine.invokeProcedure( session.getCoreSession(), procedure, values );
097        byte[] serializedResponse = SerializationUtils.serialize( ( Serializable ) response );
098        LdapApiService codec = session.getLdapServer().getDirectoryService().getLdapCodecService();
099        StoredProcedureFactory factory = ( StoredProcedureFactory ) codec.getExtendedResponseFactories().get( req.getRequestName() );
100        StoredProcedureResponse resp = ( StoredProcedureResponse ) factory.newResponse( serializedResponse );
101        resp.setMessageId( req.getMessageId() );
102        
103        session.getIoSession().write( resp );
104    }
105
106
107    /**
108     * {@inheritDoc}
109     */
110    @Override
111    public String getOid()
112    {
113        return StoredProcedureRequest.EXTENSION_OID;
114    }
115
116    private static final Set<String> EXTENSION_OIDS;
117
118    static
119    {
120        Set<String> s = new HashSet<>();
121        s.add( StoredProcedureRequest.EXTENSION_OID );
122        s.add( StoredProcedureResponse.EXTENSION_OID );
123        EXTENSION_OIDS = Collections.unmodifiableSet( s );
124    }
125
126
127    /**
128     * {@inheritDoc}
129     */
130    @Override
131    public Set<String> getExtensionOids()
132    {
133        return EXTENSION_OIDS;
134    }
135
136
137    /**
138     * {@inheritDoc}
139     */
140    @Override
141    public void setLdapServer( LdapServer ldapServer )
142    {
143    }
144}