Package org.apache.helix.josql

Source Code of org.apache.helix.josql.ClusterJosqlQueryProcessor

package org.apache.helix.josql;

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.helix.HelixDataAccessor;
import org.apache.helix.HelixException;
import org.apache.helix.HelixManager;
import org.apache.helix.HelixProperty;
import org.apache.helix.PropertyType;
import org.apache.helix.ZNRecord;
import org.apache.helix.ConfigScope.ConfigScopeProperty;
import org.apache.helix.PropertyKey.Builder;
import org.apache.helix.model.LiveInstance.LiveInstanceProperty;
import org.apache.log4j.Logger;
import org.josql.Query;
import org.josql.QueryExecutionException;
import org.josql.QueryParseException;
import org.josql.QueryResults;


public class ClusterJosqlQueryProcessor
{
  public static final String PARTITIONS = "PARTITIONS";
  public static final String FLATTABLE = ".Table";

  HelixManager _manager;
  private static Logger _logger = Logger.getLogger(ClusterJosqlQueryProcessor.class);

  public ClusterJosqlQueryProcessor(HelixManager manager)
  {
    _manager = manager;
  }

  String parseFromTarget(String sql)
  {
    // We need to find out the "FROM" target, and replace it with liveInstances
    // / partitions etc
    int fromIndex = sql.indexOf("FROM");
    if (fromIndex == -1)
    {
      throw new HelixException("Query must contain FROM target. Query: " + sql);
    }
    // Per JoSql, select FROM <target> the target must be a object class that
    // corresponds to a "table row"
    // In out case, the row is always a ZNRecord

    int nextSpace = sql.indexOf(" ", fromIndex);
    while (sql.charAt(nextSpace) == ' ')
    {
      nextSpace++;
    }
    int nextnextSpace = sql.indexOf(" ", nextSpace);
    if (nextnextSpace == -1)
    {
      nextnextSpace = sql.length();
    }
    String fromTarget = sql.substring(nextSpace, nextnextSpace).trim();

    if (fromTarget.length() == 0)
    {
      throw new HelixException("FROM target in the query cannot be empty. Query: " + sql);
    }
    return fromTarget;
  }

  public List<Object> runJoSqlQuery(String josql, Map<String, Object> bindVariables,
      List<Object> additionalFunctionHandlers, List queryTarget) throws QueryParseException,
      QueryExecutionException
  {
    Query josqlQuery = prepareQuery(bindVariables, additionalFunctionHandlers);

    josqlQuery.parse(josql);
    QueryResults qr = josqlQuery.execute(queryTarget);

    return qr.getResults();
  }

  Query prepareQuery(Map<String, Object> bindVariables, List<Object> additionalFunctionHandlers)
  {
    // DataAccessor accessor = _manager.getDataAccessor();
    HelixDataAccessor accessor = _manager.getHelixDataAccessor();
   
    // Get all the ZNRecords in the cluster and set them as bind variables
    Builder keyBuilder = accessor.keyBuilder();
//    List<ZNRecord> instanceConfigs = accessor.getChildValues(PropertyType.CONFIGS,
//        ConfigScopeProperty.PARTICIPANT.toString());
   
    List<ZNRecord> instanceConfigs = HelixProperty.convertToList(accessor.getChildValues(keyBuilder.instanceConfigs()));

    List<ZNRecord> liveInstances = HelixProperty.convertToList(accessor.getChildValues(keyBuilder.liveInstances()));
    List<ZNRecord> stateModelDefs = HelixProperty.convertToList(accessor.getChildValues(keyBuilder.stateModelDefs()));
   
    // Idealstates are stored in a map from resource name to idealState ZNRecord
    List<ZNRecord> idealStateList = HelixProperty.convertToList(accessor.getChildValues(keyBuilder.idealStates()));
   
    Map<String, ZNRecord> idealStatesMap = new HashMap<String, ZNRecord>();
    for (ZNRecord idealState : idealStateList)
    {
      idealStatesMap.put(idealState.getId(), idealState);
    }
    // Make up the partition list: for selecting partitions
    List<ZNRecord> partitions = new ArrayList<ZNRecord>();
    for (ZNRecord idealState : idealStateList)
    {
      for (String partitionName : idealState.getMapFields().keySet())
      {
        partitions.add(new ZNRecord(partitionName));
      }
    }
   
    List<ZNRecord> externalViewList = HelixProperty.convertToList(accessor.getChildValues(keyBuilder.externalViews()));
    // ExternalViews are stored in a map from resource name to idealState
    // ZNRecord
    Map<String, ZNRecord> externalViewMap = new HashMap<String, ZNRecord>();
    for (ZNRecord externalView : externalViewList)
    {
      externalViewMap.put(externalView.getId(), externalView);
    }
    // Map from instance name to a map from resource to current state ZNRecord
    Map<String, Map<String, ZNRecord>> currentStatesMap = new HashMap<String, Map<String, ZNRecord>>();
    // Map from instance name to a list of combined flat ZNRecordRow
    Map<String, List<ZNRecordRow>> flatCurrentStateMap = new HashMap<String, List<ZNRecordRow>>();

    for (ZNRecord instance : liveInstances)
    {
      String host = instance.getId();
      String sessionId = instance.getSimpleField(LiveInstanceProperty.SESSION_ID.toString());
      Map<String, ZNRecord> currentStates = new HashMap<String, ZNRecord>();
      List<ZNRecord> instanceCurrentStateList = new ArrayList<ZNRecord>();
      for (ZNRecord idealState : idealStateList)
      {
        String resourceName = idealState.getId();
       
        HelixProperty property = accessor.getProperty(keyBuilder.currentState(host, sessionId, resourceName));
        ZNRecord currentState =null;
        if (property == null)
        {
          _logger.warn("Resource " + resourceName + " has null currentState");
          currentState = new ZNRecord(resourceName);
        }else{
          currentState = property.getRecord();
        }
        currentStates.put(resourceName, currentState);
        instanceCurrentStateList.add(currentState);
      }
      currentStatesMap.put(host, currentStates);
      flatCurrentStateMap.put(host, ZNRecordRow.flatten(instanceCurrentStateList));
    }
    Query josqlQuery = new Query();

    // Set the default bind variables
    josqlQuery
.setVariable(
        PropertyType.CONFIGS.toString() + "/" + ConfigScopeProperty.PARTICIPANT.toString(),
            instanceConfigs);
    josqlQuery.setVariable(PropertyType.IDEALSTATES.toString(), idealStatesMap);
    josqlQuery.setVariable(PropertyType.LIVEINSTANCES.toString(), liveInstances);
    josqlQuery.setVariable(PropertyType.STATEMODELDEFS.toString(), stateModelDefs);
    josqlQuery.setVariable(PropertyType.EXTERNALVIEW.toString(), externalViewMap);
    josqlQuery.setVariable(PropertyType.CURRENTSTATES.toString(), currentStatesMap);
    josqlQuery.setVariable(PARTITIONS, partitions);

    // Flat version of ZNRecords
    josqlQuery.setVariable(
        PropertyType.CONFIGS.toString() + "/" + ConfigScopeProperty.PARTICIPANT.toString()
            + FLATTABLE,
        ZNRecordRow.flatten(instanceConfigs));
    josqlQuery.setVariable(PropertyType.IDEALSTATES.toString() + FLATTABLE,
        ZNRecordRow.flatten(idealStateList));
    josqlQuery.setVariable(PropertyType.LIVEINSTANCES.toString() + FLATTABLE,
        ZNRecordRow.flatten(liveInstances));
    josqlQuery.setVariable(PropertyType.STATEMODELDEFS.toString() + FLATTABLE,
        ZNRecordRow.flatten(stateModelDefs));
    josqlQuery.setVariable(PropertyType.EXTERNALVIEW.toString() + FLATTABLE,
        ZNRecordRow.flatten(externalViewList));
    josqlQuery.setVariable(PropertyType.CURRENTSTATES.toString() + FLATTABLE,
        flatCurrentStateMap.values());
    josqlQuery.setVariable(PARTITIONS + FLATTABLE, ZNRecordRow.flatten(partitions));
    // Set additional bind variables
    if (bindVariables != null)
    {
      for (String key : bindVariables.keySet())
      {
        josqlQuery.setVariable(key, bindVariables.get(key));
      }
    }

    josqlQuery.addFunctionHandler(new ZNRecordJosqlFunctionHandler());
    josqlQuery.addFunctionHandler(new ZNRecordRow());
    josqlQuery.addFunctionHandler(new Integer(0));
    if (additionalFunctionHandlers != null)
    {
      for (Object functionHandler : additionalFunctionHandlers)
      {
        josqlQuery.addFunctionHandler(functionHandler);
      }
    }
    return josqlQuery;
  }

  public List<Object> runJoSqlQuery(String josql, Map<String, Object> bindVariables,
      List<Object> additionalFunctionHandlers) throws QueryParseException, QueryExecutionException
  {
    Query josqlQuery = prepareQuery(bindVariables, additionalFunctionHandlers);

    // Per JoSql, select FROM <target> the target must be a object class that
    // corresponds to a "table row",
    // while the table (list of Objects) are put in the query by
    // query.execute(List<Object>). In the input,
    // In out case, the row is always a ZNRecord. But in SQL, the from target is
    // a "table name".

    String fromTargetString = parseFromTarget(josql);

    List fromTargetList = null;
    Object fromTarget = null;
    if (fromTargetString.equalsIgnoreCase(PARTITIONS))
    {
      fromTarget = josqlQuery.getVariable(PARTITIONS.toString());
    } else if (fromTargetString.equalsIgnoreCase(PropertyType.LIVEINSTANCES.toString()))
    {
      fromTarget = josqlQuery.getVariable(PropertyType.LIVEINSTANCES.toString());
    } else if (fromTargetString.equalsIgnoreCase(PropertyType.CONFIGS.toString() + "/"
        + ConfigScopeProperty.PARTICIPANT.toString()))
    {
      fromTarget = josqlQuery.getVariable(PropertyType.CONFIGS.toString() + "/"
          + ConfigScopeProperty.PARTICIPANT.toString());
    } else if (fromTargetString.equalsIgnoreCase(PropertyType.STATEMODELDEFS.toString()))
    {
      fromTarget = josqlQuery.getVariable(PropertyType.STATEMODELDEFS.toString());
    } else if (fromTargetString.equalsIgnoreCase(PropertyType.EXTERNALVIEW.toString()))
    {
      fromTarget = josqlQuery.getVariable(PropertyType.EXTERNALVIEW.toString());
    }
    else if (fromTargetString.equalsIgnoreCase(PropertyType.IDEALSTATES.toString()))
    {
      fromTarget = josqlQuery.getVariable(PropertyType.IDEALSTATES.toString());
    }
   
    else if (fromTargetString.equalsIgnoreCase(PARTITIONS + FLATTABLE))
    {
      fromTarget = josqlQuery.getVariable(PARTITIONS.toString() + FLATTABLE);
    } else if (fromTargetString.equalsIgnoreCase(PropertyType.LIVEINSTANCES.toString() + FLATTABLE))
    {
      fromTarget = josqlQuery.getVariable(PropertyType.LIVEINSTANCES.toString() + FLATTABLE);
    } else if (fromTargetString.equalsIgnoreCase(PropertyType.CONFIGS.toString() + "/"
        + ConfigScopeProperty.PARTICIPANT.toString()
        + FLATTABLE))
    {
      fromTarget = josqlQuery.getVariable(PropertyType.CONFIGS.toString() + "/"
          + ConfigScopeProperty.PARTICIPANT.toString() + FLATTABLE);
    } else if (fromTargetString
        .equalsIgnoreCase(PropertyType.STATEMODELDEFS.toString() + FLATTABLE))
    {
      fromTarget = josqlQuery.getVariable(PropertyType.STATEMODELDEFS.toString() + FLATTABLE);
    } else if (fromTargetString.equalsIgnoreCase(PropertyType.EXTERNALVIEW.toString() + FLATTABLE))
    {
      fromTarget = josqlQuery.getVariable(PropertyType.EXTERNALVIEW.toString() + FLATTABLE);
    }
    else if (fromTargetString.equalsIgnoreCase(PropertyType.IDEALSTATES.toString() + FLATTABLE))
    {
      fromTarget = josqlQuery.getVariable(PropertyType.IDEALSTATES.toString() + FLATTABLE);
    }
    else
    {
      throw new HelixException(
          "Unknown query target "
              + fromTargetString
              + ". Target should be PARTITIONS, LIVEINSTANCES, CONFIGS, STATEMODELDEFS, IDEALSTATES, EXTERNALVIEW, and corresponding flat Tables");
    }

    fromTargetList = fromTargetString.endsWith(FLATTABLE) ? ((List<ZNRecordRow>) fromTarget)
        : ((List<ZNRecord>) fromTarget);

    // Per JoSql, select FROM <target> the target must be a object class that
    // corresponds to a "table row"
    // In out case, the row is always a ZNRecord
    josql = josql.replaceFirst(
        fromTargetString,
        fromTargetString.endsWith(FLATTABLE) ? ZNRecordRow.class.getName() : ZNRecord.class
            .getName());
    josqlQuery.parse(josql);
    QueryResults qr = josqlQuery.execute(fromTargetList);
    return qr.getResults();
  }
}
TOP

Related Classes of org.apache.helix.josql.ClusterJosqlQueryProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.