/*-
 * ============LICENSE_START=======================================================
 * OSAM
 * ================================================================================
 * Copyright (C) 2018 AT&T
 * ================================================================================
 * Licensed 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.
 * ============LICENSE_END=========================================================
 */
package org.onap.osam.job;

import org.onap.osam.job.dao.job.JobStatus;
import org.onap.osam.job.dao.job.OsamJob;
import org.onap.osam.job.impl.JobSharedData;

import java.util.Map;
import java.util.UUID;

/**
 * kind of factory for creating jobs and converting them to Job Model
 */
public interface IJobFactory {
/*
    JobModel toModel(Job job);
*/

    OsamJob createRootJob(JobType jobType, AsyncJobRequest request, String userId, Integer indexInBulk, Map<String, Object> jobData);

    OsamJob createChildJob(JobType jobType, JobStatus jobStatus, AsyncJobRequest request, JobSharedData parentSharedData, Map<String, Object> jobData);

    // Marks types that are an AsyncJob payload
    interface AsyncJobRequest {
    }

}
