Skip to main content

Mapeamento de campo personalizado do arquivo simples do Snapshot

Mapeamento de campo

A estrutura do Sistema de informações do aluno (SIA) oferece suporte à personalização de dados recebidos antes de serem adicionados ao Blackboard registro por registro. Isso é útil quando os dados do Sistema de informações do aluno (SIA) não estão alinhados com os requisitos de dados do Blackboard e não podem ser alterados no Sistema de informações do aluno (SIA) porque são proibitivos ou as informações que os dados representam são usadas por outros sistemas. Este documento aborda o uso da opção "Mapeamento de campo", especificamente como usar a opção de mapeamento de campo script personalizado.

Essa capacidade de personalizar os dados de entrada é chamada de Mapeamento de campo e é acessada na interface do usuário no menu Configuração avançada da integração.

A tela Configuração avançada fornece uma lista dos objetos compatíveis com esse objeto no Blackboard.

A tela Configuração avançada fornece uma lista dos objetos compatíveis com esse objeto no Blackboard. Esses alinhamentos com o tipo de integração variam de tipo de integração para tipo de integração.

Campo de mapeamento de campo selecionado na tela Configuração avançada

Quando você seleciona Mapeamento de campo em um objeto do Learn associado ao tipo de integração, neste caso Cursos, você será direcionado para a página Mapeamento de campo para a integração.

Página Mapeamento de campo para a integração após selecionar o tipo de integração

Além de informações úteis sobre o campo, como se é necessário para inserir ou se deve ser exclusivo, você também pode selecionar várias configurações que controlam como os dados de entrada são gerenciados pela integração e se você escolhe mapear entre objetos de entrada.

Na tela Configuração avançada, escolha as configurações que controlam como os dados recebidos são gerenciados pela integração
Scripts personalizados e mapeamento de campo

No campo que você deseja fornecer um mapeamento de campo, você pode selecionar para usar um campo de entrada diferente. Por exemplo: digamos que a ID do curso recebida não seja adequada para seu uso no Blackboard, você pode mapeá-la para o código externo do curso. Como este tutorial é sobre como usar um script personalizado para realizar o mapeamento, você selecionaria 'Usar um script personalizado' no menu suspenso 'Campo de origem'.

Os scripts personalizados são baseados em JavaScript. Todos os dados de entrada são mapeados para um modelo de objeto interno que permite acessar cada elemento dos respectivos dados e subsequente uso ou manipulação usando um JavaScript personalizado.

Use comparadores inteiros em instruções switch JavaScript. Se você precisar usar sequências de caracteres ou caracteres como comparadores, use declarações if/else em vez de alterar as declarações.

Duas excelentes referências JavaScript são fornecidas pelo Mozilla Developer Network https://developer.mozilla.org/en-US/...ript/Reference e pelo Consórcio da Web Mundial (W3C) http://www.w3schools.com/jsref/.

Dados de entrada mapeados para um modelo de objeto interno

Selecionar "Usar um script personalizado" fornece uma área de texto para inserir seu código javascript.

Opção 'Usar um script personalizado' selecionada

É nessa área de texto que você inserirá seu script personalizado para editar os dados de entrada.

Documentação no Blackboard

A documentação sobre scripts de mapeamento de campo personalizado pode ser encontrada na página Documentos de amostra vinculada à página Integrações do sistema de informações do Aluno de nível superior no Painel do administrador do Blackboard.

O link Documentos de amostra encontrou a página de nível superior Integrações do sistema de informações do Aluno no Painel do administrador da Blackboard.

O link Documentos de Amostra abre uma página que contém vários links para documentos da Estrutura de Integração do SIA que abrangem todos os tipos de integração. Os dois documentos de interesse no contexto do tipo de integração de arquivo simples do Snapshot e Mapeamento de Campo Personalizado são vinculados pelo Dicionário de Dados: Integração de arquivo simples do Snapshot e Exemplos de Script de Mapeamento de Campo Personalizado, respectivamente.

A página Documentos de exemplo contém vários links para documentos da Estrutura de Integração do Sistema de informações do aluno (SIA) que abrangem todos os tipos de integração.
Scripts personalizados

O acesso ao modelo de objeto de cada tipo de integração é diferente e baseado na estrutura de dados subjacente da especificação de dados do tipo de integração. A partir de um entendimento da especificação de dados de integração, você pode gerar um padrão para acessar todos os objetos da integração.

No caso do arquivo simples do Snapshot, esse padrão é baseado em um objeto raiz de "dados" para que possamos gerar o seguinte padrão:

data.getValue(<FlatFileDataObject>);

em que <FlatFileDataObject> é substituído pelo nome do elemento de cabeçalho do feed de dados.

Por exemplo:

data.getValue("firstname");

data.getValue("lastname");

data.getValue("course_name");

Além disso, quando o feed de dados assume um 'Y' ou 'N', você deve substituir condicionalmente como resultado do script pelos valores booleanos true ou false, respectivamente. Por exemplo:

var avail_ind = false;

if (data.getValue("available_ind").toUpperCase() == 'Y') {

avail_ind=true;

avail_ind;

ou de forma alternativa, escrito usando uma instrução usando um operador ternário:

condição? Executar se a condição for verdadeira: Executar se a condição for falsa :

Por exemplo:

data.getValue("available_ind").toUpperCase( )=='Y' ? avail_ind = true : avail_ind = false;

avail_ind;

o acima pode ser reduzido ainda mais para apenas a instrução ternária, uma vez que é o valor final da expressão na última linha do script que é retornado como o ponto de dados salvo no Blackboard.

Assim, podemos usar:

data.getValue("available_ind").toUpperCase() == 'Y' ? avail_ind = true : avail_ind = false;

e obter o mesmo resultado.

Dado que os scripts personalizados são processados por registro, o desempenho da integração pode ser afetado se scripts computacionalmente intensivos (como criptografia) forem executados. Observe também que não há compatibilidade de acesso a dados externos: você pode executar apenas operações em dados de feed existentes ou dados gerados por computação.

Depuração de scripts

Depurar seus Scripts é relativamente fácil, pois os erros ou problemas de dados que você pode encontrar são registrados.

Por exemplo:

Devido ao desenvolvimento de um script personalizado no campo "Disponível":

data.getValue("available_ind");

pode ser executado com sucesso, mas se o valor não for passado no feed de dados, o script produzirá a seguinte entrada no Log:

Valor nulo retornado para atributo não anulável: isAvailable.

Dados inválidos para o atributo: isAvailable. Valor: null. Usar o valor padrão do Blackboard.

Quando (presumindo que available_ind seja fornecida no feed):

data.getValue("available_ind");

pode ser executado com sucesso, mas produzir a seguinte entrada no Log:

Tipo de valor inválido para attribute: isAvailable. Valor: y

Dados inválidos para o atributo: isAvailable. Valor: Y. Usar o valor padrão do Blackboard.

isso ocorre porque precisamos alterar condicionalmente os dados de entrada para o valor booleano esperado – neste caso, "TRUE", para que pudéssemos alterar o script para:

data.getValue("available_ind") == 'y'?true:false;

Mas, para ter certeza, queremos capturar comparações de maiúsculas e minúsculas para ajustarmos o script:

data.getValue("available_ind").toUpper() == 'Y' ? true : false;

Isso resultará em um erro de script real e será impresso no log:

Erro na execução do script para o atributo: isAvailable.

blackboard.platform.script.ScriptingException: javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "toUpper" is not defined. (<Unknown Source>#2) in <Unknown Source> at line number 2

Isso ocorre porque o JavaScript não tem toUpper(), mas tem toUpperCase() então editar o script ...

data.getValue("available_ind").toUpperCase() =='Y' ? true : false;

agora o script será executado com sucesso.

Scripts auxiliares: Registrando em scripts personalizados

O aplicativo Blackboard fornece scripts auxiliares para fornecer recursos comuns, como registro para seus scripts. Adicionar o seguinte em seus scripts incluirá a saída nos registros de integração:

helper.logError(msg)

helper.logWarning(msg)

helper.logInfo(msg)

helper.logDebug(msg)

A saída dos métodos helper.log* será visível em registros com base na configuração de integração para níveis de registro.

Scripts auxiliares adicionais disponíveis (conforme descrito na página Exemplos de Script de Mapeamento de Campo Personalizado vinculada à Página de Documentos de Exemplo) são:

  • helper.getBatchUid( String id ) – Isso constrói um identificador prefixado com o código de identificação do lote específico para a integração do Sistema de informações do aluno (SIA) na qual o mapeamento está sendo executado. Isso deve ser usado sempre que gerar códigos "exclusivos", pois o prefixo pode ajudar a evitar conflitos de código.

  • helper.getHelper( String helperName ) – Retorna um objeto auxiliar específico do tipo de integração do Sistema de informações do aluno (SIA) que contém métodos auxiliares aplicáveis a esse tipo de integração. A documentação para esses scripts de ajuda será fornecida nos JavaDocs para cada Tipo de integração do SIA.

  • helper.skipAttribute() – Isso retorna um valor que, quando retornado de um script de mapeamento, faz com que o campo que está sendo mapeado seja ignorado (não alterado).

  • helper.skipAttributeIfNull( Object value ) – Se o valor passado for nulo, isso retornará a mesma coisa que skipAttribute. Se não for nulo, o valor será devolvido.

  • helper.skipRecord() – Retorna um valor que, quando retornado de um script de mapeamento, faz com que todo o registro que está sendo processado no momento seja ignorado.

  • helper.skipRecordIfNull( Object value ) – Se o valor passado for nulo, isso retornará a mesma coisa que skipRecord. Se não for nulo, o valor será devolvido.

Continuando com nosso script de amostra, adicionaremos uma mensagem de registro de informações para indicar que o valor usado no Blackboard é derivado de um script personalizado, o objeto de dados base referenciado para os dados inseridos e os valores calculados que foram usados. Também adicionaremos uma mensagem de registro indicando uma condição de erro baseada na falta de um script disponível adequado.

Revisitando o que foi mencionado acima, digamos que o AVAILABLE_IND seja definido de forma inconsistente nos feeds de dados do curso, o que significa que nem sempre está presente no feed de dados, e que você quer configurá-lo como verdadeiro quando um valor para AVAILABLE_IND não estiver presente ou avaliar adequadamente? O script agora se torna:

var outInd = false;

var inInd = data.getValue("available_ind")

if (inInd == "") {

helper.logInfo("INCOMING AVAILABLE_IND UNDEFINED for "+data.getValue("course_id")+": setting isAvailable to true");

outInd=true;

} else {

data.getValue("available_ind").toUpperCase()=='Y'?outInd=true:outInd=false;

}

helper.logInfo("OUTGOING AVAILABLE_IND: ["+outInd+"]");

outInd;

O registro agora é exibido:

31 de maio de 2013 16:03:56 – Curso [criar/atualizar, testCourse1]

INCOMING AVAILABLE_IND UNDEFINED for TEST_COURSE_1: setting isAvailable to true

OUTGOING AVAILABLE_IND: [true]

Curso 'testCourse1' processado com sucesso.

testCourse1|TEST_COURSE_1|Test Course 1|

...

entradas de registro restantes

...

Mapeamento de campo bem-sucedido.

Exemplos
  • Nomes do curso

  • Senhas

  • E-mails

Nome do curso: Adicionar período e ano
Caso de uso

É desejado que a exibição dos cursos contenha o período e o ano em que o curso é oferecido. Atualmente, os dados fornecidos pelo SIA não anexam essas informações ao course_name. Os cursos são exibidos usando o nome do curso. Por exemplo:

Exemplo de um nome de curso encontrado na área Meus Cursos
Pré-condição

O SIA fornece o período e o ano como parte da string course_id e fornece o campo course_name obrigatório.

Por exemplo:

external_course_key|course_id|course_name|available_ind

ARTHIST.202.01|36202010114|Art History 202: Renaissance Architecture|Y

No exemplo acima, o código do curso é composto por:

O departamento: 36

O curso: 202

a seção: 01

o mês do período: 01

o ano: 14

Requisitos

1. Os períodos são determinados pelo mês designado. Por exemplo:

01 = Inverno

04 = Primavera

06 = Verão

09 = Queda

2. Inclua o período e o ano gerados programaticamente ao nome do curso, separados por espaços e encerrado entre parênteses "()". Por exemplo:

História da Arte 202: Arquitetura Renascentista (Inverno de 2014)

3. Ignore o acréscimo de informações se o período adequado não for fornecido.

Condição a posteriori

1. Os cursos em que o course_id fornece identificadores de período/ano adequados terão os dados de course_name anexados com (PERÍODO ANO) antes da criação ou atualização do registro do curso no Blackboard.

2. Cursos sem identificadores adequados de período/ano no course_id não terão alteração em course_name.

Roteiro

O nome do curso é fornecido no campo course_name do feed de dados do SIA e as informações obrigatórias do período estão contidas no campo course_id dos elementos do feed de dados do SIA em formato numérico. Para atender aos requisitos necessários para

a) determinar o ano e

b) determinar o período pelo mapeamento de um intervalo e, em seguida, formatar corretamente os dados resultantes.

Isso faremos ao fornecer funções de javascript para devolver o formato desejado para a exibição do nome do curso e colocar o resultado dessas funções no formato adequado.

Nota

Os tutoriais para redação de funções de javascript são fornecidos nos sites HTMLGoodies (http://www.htmlgoodies.com/beyond/ja...d-classes.html) and the World Wide Web Consortium (W3C) (http://www.w3schools.com/js/js_functions.asp).

a) Determine o ano.

Dado o course_id contém um ano de dois números no final da sequência de caracteres, podemos escrever uma função para puxar e retornar os dois últimos caracteres:

function courseYear(crn) {

return crn.substring(9);

}

b) Determine o prazo.

O course_id também nos fornece os dados para determinar o período e podemos usar a função de substring JavaScript para extrair os dados MM e mapeá-los para um intervalo de meses que representa um rótulo de período – Por exemplo: 09 = Outono, 01 = Inverno, 04 = Primavera, 06 = Verão

Nota

Esse é um caso simplista – os dados também podem fornecer datas de início que poderiam ser usadas em conjunto com o course_id para determinar condicionalmente o período.

function getTerm(crn) {

var termCode=crn.substring(7, 9);

var term="";

if (termCode == "01") {

term="Winter";

} else if (termCode == "04") {

term="Spring";

} else if (termCode == "06") {

term="Summer";

} else if (termCode == "09") {

term="Fall";

} else {

term="";

}

return term;

}

function getYear(crn) {

return crn.substring(9);

}

Porque estamos trabalhando com números inteiros aqui, podemos escrever a função getTerm usando uma instrução de troca em vez da anterior, que usa if/else...

function getTerm(crn) {

var termCode = parseInt(crn.substring(7,9));

var term = "";

switch (termCode)

{

case 09: term ="Fall"; break;

case 01: term ="Winter"; break;

case 04: term ="Spring"; break;

case 06: term ="Summer"; break;

default: term ="";

}

return termString ;

}

Nota

A declaração de troca funciona apenas porque podemos gerar um número inteiro para o comparador.

Agora que temos funções para determinar o período e o ano, vamos escrever o script que anexa o course_name:

function getTerm(crn) {

var termCode=crn.substring(7, 9);

var term="";

if (termCode == "01") {

term="Winter";

} else if (termCode == "04") {

term="Spring";

} else if (termCode == "06") {

term="Summer";

} else if (termCode == "09") {

term="Fall";

} else {

term="";

}

return term;

}

function getYear(crn) {

return crn.substring(9);

}

var crn = data.getValue("course_id");

var year = getYear(crn);

var term = getTerm(crn);

var courseName = data.getValue("course_name");

var newCourseName = "";

if (term!="") {

newCourseName = courseName + " (" + term + " 20" + year + ")";

} else {

newCourseName = courseName;

}

helper.logInfo("INCOMING COURSE_NAME " + data.getValue("course_name"));

helper.logInfo("INCOMING COURSE CRN " + crn);

helper.logInfo("INCOMING COURSE YEAR " + year);

helper.logInfo("INCOMING COURSE TERM " + term);

helper.logInfo("INCOMING COURSE_NAME " + data.getValue("course_name"));

helper.logInfo("OUT NEW NAME " + newCourseName);

newCourseName;

Inserindo o acima no mapeamento de campo do curso para Nome do curso e, usando a opção de integração Carregar arquivo, carregando (armazenando) manualmente o exemplo de feed do curso da pré-condição acima, você verá os dados abaixo postados nos registros do nosso curso de amostra:

Detalhes da mensagem postada nos registros do curso de amostra

E o nome do curso agora será exibido com o período e o ano derivados do course_id.

Senhas
Caso de uso

Você usa o LDAP para autenticar usuários do Blackboard, mas o Blackboard exige senhas para criar contas de usuário e seu Sistema de informações do aluno (SIA) não fornece senhas. Você precisa criar uma senha aleatória por usuário.

Pré-condição

O feed de dados fornece as informações básicas do usuário que podem ser usadas para criar a senha. Por exemplo: nome e sobrenome

Requisitos

As senhas devem ser a combinação de nome+sobrenome+número aleatório

Deve ser capaz de especificar um intervalo para a randomização

Condição a posteriori

A senha é criada para o usuário Por exemplo:

Para o usuário Barney Rubble, a senha pode ser barneyrubble102464

Dados de amostra

external_person_key|user_id|passwd|firstname|lastname|email|system_role

testPerson1|aanderson_test|changeme|Alpha|Anderson||none

testPerson2|bvonbrown_test|changeme|Beta|Von Brown||none

testPerson3|ddavis_test|changeme|Delta|Davis!||none

testPerson4|ggardner_test|changeme|Gamma|G'Ardner||none

Roteiro

função rand (min, max) {

var argc = argumentos.comprimento;

if (argc === 0) {

min = 0;

max = 2147483647;

}

return Math.floor(Math.random() * (max – min + 1)) + min;

}

var senha = "";

var regex = new RegExp(" ", 'g');

helper.logInfo("INCOMING PASSWORD: " + data.getValue("passwd"));

helper.logInfo("INCOMING FIRSTNAME: " + data.getValue("firstname"));

helper.logInfo("INCOMING LASTNAME: " + data.getValue("lastname"));

password = (data.getValue("firstname") + data.getValue("lastname") + rand() + rand()).toUpperCase();

senha = senha.replace(regex, '');

helper.logInfo("GENERATED PASSWORD: " + password);

senha;

Inserindo o acima no mapeamento do campo Usuário para Senha e carregando (armazenando) manualmente o exemplo de feed do Usuário (Pessoa) dos dados de amostra acima, você verá os dados abaixo postados nos logs:

alt
E-mails

Nota

Os e-mails podem ser complicados de validar corretamente e alguns argumentam que nunca se deve fazer isso com uma expressão simples regular ou em um javascript. O exemplo abaixo é um exemplo de alto nível que, embora provavelmente corresponda corretamente a 95% ou mais dos endereços de e-mail passados, pode perder alguns exemplos de casos extremos e, portanto, pretende ser mais um exemplo de como alguém abordaria a criação de endereços de e-mail e o uso de captura de erros em um script de mapeamento de campo personalizado do que um exercício de validação de e-mail.

Caso de uso

Seu Sistema de informações do aluno (SIA) não armazena contas de e-mail de Alunos ou contas de e-mail pessoais, mas não aquelas emitidas por sua instituição – você deseja que os e-mails no Blackboard sejam as contas de e-mail emitidas pela instituição.

Pré-condição

Os dados necessários para gerar a parte local do endereço de e-mail desejado existem no feed de dados do SIA. Por exemplo: nome e sobrenome

Requisitos

As contas de e-mail emitidas pela instituição seguem o padrão de [email protected] onde '-yy' representa o ano previsto de formatura para o aluno. Esses elementos são transmitidos no feed do SIA nos seguintes dados:

FIRSTNAME: primeiro nome do aluno

MIDDLENAME: o nome do meio do aluno

LASTNAME: o sobrenome do aluno

OTHERNAME: o ano da formatura

A parte local dos endereços de e-mail aceitáveis deve conter apenas alfanuméricos, "-',_','." e apóstrofos. Por exemplo: Gamma.G'[e-mail protegido]

Condição a posteriori

Um endereço de e-mail formatado corretamente é gerado e passado para o Blackboard.

Dados de amostra

external_person_key|user_id|passwd|firstname|lastname|email|system_role

testPerson1|aanderson_test|changeme|Alpha|Anderson||none

testPerson2|bvonbrown_test|changeme|Beta|Von Brown||none

testPerson3|ddavis_test|changeme|Delta|Davis!||none

testPerson4|eedwards_test|changeme|E...nstitution.edu|none

testPerson5|ggardner_test|changeme|Gamma|G'Ardner||none

Roteiro

var e-mailAddress = "";

var instDomain = "institution.edu";

function buildIt() {

var fname = data.getValue("firstname");

var lname = data.getValue("lastname");

var regex = new RegExp(" ", 'g');

endereçoDeE_e-mail = fname +"." +lname+"@"+instDomain;

e-mailAddress=e-mailAddress.toLowerCase();

endereçoDeE_e-mail = endereçoDeE_e-mail.replace(regex, '');

}

function validateIt(eAddress) {

var emailRegEx = /^([a-zA-Z0-9_\.\-\'])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;

if (!emailRegEx.test(eAddress))

throw new Error("Erro do validador de e-mail: não é possível validar o endereço de e-mail");

}

emailAddress = data.getValue("email");

if (emailAddress == "" || emailAddress == null) {

buildIt();

} else if ( emailAddress.indexOf(instDomain) === -1) {

buildIt()

}

tente {

validateIt(emailAddress);

} catch (err) {

helper.logError("INCOMING EMAIL ADDRESS: " + emailAddress);

helper.logError("INCOMING FIRSTNAME: " + data.getValue("firstname"));

helper.logError("INCOMING LASTNAME: " + data.getValue("lastname"));

helper.logError(err +" for User (" + data.getValue("user_id") +", Email (" + emailAddress + "). Nenhum endereço de e-mail salvo para este usuário. )");

emailAddress="";

}

helper.logInfo("emailAddress: " + emailAddress);

endereço de e-mail;

Inserindo o acima no mapeamento do campo Usuário para Senha e carregando (armazenando) manualmente o exemplo de feed do Usuário (Pessoa) dos dados de amostra acima, você verá um erro postado nos logs.

Isso ocorre porque os endereços de e-mail não podem conter pontos de exclamação pela nossa expressão regular.

Observe que o usuário ainda é criado, pois um endereço de e-mail válido não é necessário para criar ou atualizar um registro de usuário.

Alterando a entrada de Delta Davis de:

testPerson4|ddavis_test|changeme|Delta|Davis!||none

para

testPerson4|ddavis_test|changeme|Delta|Davis||none

excluir o '!' no campo lastname da Delta e recarregar o arquivo exclui o erro e atualiza o registro da Delta com o novo endereço de e-mail.

Ignorando um registro ou atributo em caso de erro

O Helper fornece dois métodos adicionais que permitem um controle ainda maior sobre o processamento em seus scripts:

helper.skipAttribute() – ignora um atributo não crítico que parece estar definido incorretamente

helper.skipRecord() – para pular o registro inteiro e passar para o próximo

O script de e-mail acima registra um erro quando o endereço de e-mail não pode ser validado, mas também continua a criar o registro mesmo assim. Se não quisermos criar usuários com e-mails vazios, mas em vez disso registrar o erro de validação e passar para o próximo registro, adicionaríamos helper.skipRecord() em uma condicional baseada em emailAddress no final do script. Por exemplo:

em vez de fechar o script com e-mailAddress=""; Feche com:

(emailAddress=="") ? helper.skipRecord(): emailAddress;

Isso ignora condicionalmente o registro com base no conteúdo do emailAddress que definimos como uma sequência de caracteres vazia quando a validação falhou.

Adicione o método helper.skipRecord() ao script e altere a entrada para Delta Davis de:

testPerson4|ddavis_test|changeme|Delta|Davis||none

para

testPerson4|ddavis_test|changeme|Delta|Davis!||none

Carregando (armazenando) manualmente o exemplo de feed do usuário (pessoa) revisado – com ponto de exclamação, você verá os dados postados nos registros.

O erro de registro de salto aparece no final do log, ele observa que o registro foi ignorado como resultado do script de mapeamento e do atributo que retornou o resultado.

Observe que o erro é registrado e que ao final do registro ele informa que o registro foi ignorado em decorrência do script de mapeamento e do atributo que retornou o resultado.

A aplicação condicional de helper.skipAttribute() terá o mesmo impacto – o script processará os dados do feed e, com base na presença de uma condicional como a linha final chamando helper.skipAttribute(), a integração lançará um erro e pulará o registro ou, se o atributo não for necessário, a configuração de mapeamento assumirá o controle e manipulará o atributo conforme configurado.