Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright Debezium Authors.
*
* Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package io.debezium.ibmi.db2.journal.retrieve;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.AS400Bin4;
import com.ibm.as400.access.AS400Bin8;
import com.ibm.as400.access.AS400DataType;
import com.ibm.as400.access.AS400Message;
import com.ibm.as400.access.AS400Structure;
import com.ibm.as400.access.AS400Text;
import com.ibm.as400.access.FileAttributes;
import com.ibm.as400.access.ProgramCall;
import com.ibm.as400.access.ProgramParameter;
import com.ibm.as400.access.QSYSObjectPathName;
import com.ibm.as400.access.ServiceProgramCall;
import io.debezium.ibmi.db2.journal.retrieve.rnrn0200.DetailedJournalReceiver;
import io.debezium.ibmi.db2.journal.retrieve.rnrn0200.JournalReceiverInfo;
import io.debezium.ibmi.db2.journal.retrieve.rnrn0200.JournalStatus;
import io.debezium.ibmi.db2.journal.retrieve.rnrn0200.KeyDecoder;
import io.debezium.ibmi.db2.journal.retrieve.rnrn0200.KeyHeader;
import io.debezium.ibmi.db2.journal.retrieve.rnrn0200.ReceiverDecoder;
/**
* @see http://www.setgetweb.com/p/i5/rzakiwrkjrna.htm
* @author sillencem
*
*/
public class JournalInfoRetrieval {
private static final Logger log = LoggerFactory.getLogger(JournalInfoRetrieval.class);
public static final String JOURNAL_SERVICE_LIB = "/QSYS.LIB/QJOURNAL.SRVPGM";
private static final byte[] EMPTY_AS400_TEXT = new AS400Text(0).toBytes("");
private static final AS400Text AS400_TEXT_8 = new AS400Text(8);
private static final AS400Text AS400_TEXT_20 = new AS400Text(20);
private static final AS400Text AS400_TEXT_1 = new AS400Text(1);
private static final AS400Text AS400_TEXT_10 = new AS400Text(10);
private static final AS400Bin8 AS400_BIN8 = new AS400Bin8();
private static final AS400Bin4 AS400_BIN4 = new AS400Bin4();
private static final int KEY_HEADER_LENGTH = 20;
private final DetailedJournalReceiverCache cache = new DetailedJournalReceiverCache();
public JournalInfoRetrieval() {
super();
}
public JournalPosition getCurrentPosition(AS400 as400, JournalInfo journalLib) throws Exception {
final JournalReceiver ji = JournalInfoRetrieval.getReceiver(as400, journalLib);
final BigInteger offset = getOffset(as400, ji).end();
return new JournalPosition(offset, ji);
}
public DetailedJournalReceiver getCurrentDetailedJournalReceiver(AS400 as400, JournalInfo journalLib)
throws Exception {
final JournalReceiver ji = JournalInfoRetrieval.getReceiver(as400, journalLib);
return getOffset(as400, ji);
}
static final Pattern JOURNAL_REGEX = Pattern.compile("\\/[^/]*\\/([^.]*).LIB\\/(.*).JRN");
@Deprecated
public static JournalInfo getJournal(AS400 as400, String schema) throws IllegalStateException {
// https://stackoverflow.com/questions/43061626/as-400-create-journal-jt400-java
// note each file can have it's own different journal
try {
final FileAttributes fa = new FileAttributes(as400, String.format("/QSYS.LIB/%s.LIB", schema));
final Matcher m = JOURNAL_REGEX.matcher(fa.getJournal());
if (m.matches()) {
return new JournalInfo(m.group(2), m.group(1));
}
else {
log.error("no match searching for journal filename {}", fa.getJournal());
}
}
catch (final Exception e) {
throw new IllegalStateException("Journal not found", e);
}
throw new IllegalStateException("Journal not found");
}
public static JournalInfo getJournal(AS400 as400, String schema, List includes)
throws IllegalStateException {
if (includes.isEmpty()) {
return getJournal(as400, schema);
}
try {
final Set jis = new HashSet<>();
for (final FileFilter f : includes) {
if (!schema.equals(f.schema())) {
throw new IllegalArgumentException(
String.format("schema %s does not match for filter: %s", schema, f));
}
final JournalInfo ji = getJournal(as400, f.schema(), f.table());
jis.add(ji);
}
if (jis.size() > 1) {
throw new IllegalArgumentException(
String.format("more than one journal for the set of tables journals: %s", jis));
}
return jis.iterator().next();
}
catch (final Exception e) {
throw new IllegalStateException("unable to retrieve journal details", e);
}
}
public static JournalInfo getJournal(AS400 as400, String schema, String table) throws Exception {
final int rcvLen = 32768;
final String filename = padRight(table.toUpperCase(), 10) + padRight(schema.toUpperCase(), 10);
final ProgramParameter[] parameters = new ProgramParameter[]{
new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, rcvLen), // 1
// Receiver
// variable
// (output)
new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, AS400_BIN4.toBytes(rcvLen)), // 2
// Length
// of
// receiver
// variable
new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, 20), // 3
// Qualified
// returned
// file
// name
// (output)
new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, AS400_TEXT_8.toBytes("FILD0100")), // 4
// Format
// name
new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, AS400_TEXT_20.toBytes(filename)), // 5
// Qualified
// file
// name
new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, AS400_TEXT_10.toBytes("*FIRST")), // 6
// Record
// format
// name
new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, AS400_TEXT_1.toBytes("0")), // 7
// Override
// processing
new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, AS400_TEXT_10.toBytes("*LCL")), // 8
// System
new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, AS400_TEXT_10.toBytes("*INT")), // 9
// Format
// type
new ProgramParameter(ProgramParameter.PASS_BY_REFERENCE, AS400_BIN4.toBytes(0)), // 10
// Error
// Code
};
final ProgramCall pc = new ProgramCall();
pc.setSystem(as400);
final QSYSObjectPathName programName = new QSYSObjectPathName("QSYS", "QDBRTVFD", "PGM");
pc.setProgram(programName.getPath(), parameters);
final boolean success = pc.run();
if (success) {
final byte[] data = parameters[0].getOutputData();
final int offsetJournalHeader = decodeInt(data, 378);
int offsetJournalOrn = decodeInt(data, offsetJournalHeader + 378);
offsetJournalOrn += offsetJournalHeader;
final String journalName = decodeString(data, offsetJournalOrn, 10);
final String journalLib = decodeString(data, offsetJournalOrn + 10, 10);
return new JournalInfo(journalName, journalLib);
}
else {
final String msg = Arrays.asList(pc.getMessageList()).stream().map(AS400Message::getText).reduce("",
(a, s) -> a + s);
throw new IllegalStateException(String.format("Journal not found for %s.%s error %s", schema, table, msg));
}
}
public static class JournalRetrievalCriteria {
private static final AS400Text AS400_TEXT_1 = new AS400Text(1);
private static final Integer ZERO_INT = Integer.valueOf(0);
private static final Integer TWELVE_INT = Integer.valueOf(12);
private static final Integer ONE_INT = Integer.valueOf(1);
private final ArrayList structure = new ArrayList<>();
private final ArrayList