很快。我找到了一个article https://communities.sas.com/t5/tkb/articleprintpage/tkb-id/library/article-id/1667?attachment-id=9295这可以告诉我们如何为这个问题创建存储过程。我的回答是对文章的补充。
该方法基于从 sas 程序执行 java 方法。
1. 前置setPasswd.java类
我已经修改了文章中的类。连接到元数据服务器并创建的单独代码InternalLogin
import java.rmi.RemoteException;
import com.sas.metadata.remote.AssociationList;
import com.sas.metadata.remote.CMetadata;
import com.sas.metadata.remote.Person;
import com.sas.metadata.remote.MdException;
import com.sas.metadata.remote.MdFactory;
import com.sas.metadata.remote.MdFactoryImpl;
import com.sas.metadata.remote.MdOMIUtil;
import com.sas.metadata.remote.MdOMRConnection;
import com.sas.metadata.remote.MdObjectStore;
import com.sas.metadata.remote.MetadataObjects;
import com.sas.metadata.remote.PrimaryType;
import com.sas.metadata.remote.Tree;
import com.sas.meta.SASOMI.ISecurity_1_1;
import com.sas.iom.SASIOMDefs.VariableArray2dOfStringHolder;
public class setPasswd {
String serverName = null;
String serverPort = null;
String serverUser = null;
String serverPass = null;
MdOMRConnection connection = null;
MdFactoryImpl _factory = null;
ISecurity_1_1 iSecurity = null;
MdObjectStore objectStore = null;
Person person = null;
public int connectToMetadata(String name, String port, String user, String pass){
try {
serverName = name;
serverPort = port;
serverUser = user;
serverPass = pass;
_factory = new MdFactoryImpl(false);
connection = _factory.getConnection();
connection.makeOMRConnection(serverName, serverPort, serverUser, serverPass);
iSecurity = connection.MakeISecurityConnection();
return 0;
}catch(Exception e){
return 1;
}
}
public setPasswd(){};
public int changePasswd(String IdentityName, String IdentityPassword) {
try
{
//
// This block obtains the person metadata ID that is needed to change the password
//
// Defines the GetIdentityInfo 'ReturnUnrestrictedSource' option.
final String[][] options ={{"ReturnUnrestrictedSource",""}};
// Defines a stringholder for the info output parameter.
VariableArray2dOfStringHolder info = new VariableArray2dOfStringHolder();
// Issues the GetInfo method for the provided iSecurity connection user.
iSecurity.GetInfo("GetIdentityInfo","Person:"+IdentityName, options, info);
String[][] returnArray = info.value;
String personMetaID = new String();
for (int i=0; i< returnArray.length; i++ )
{
System.out.println(returnArray[i][0] + "=" + returnArray[i][1]);
if (returnArray[i][0].compareTo("IdentityObjectID") == 0) {
personMetaID = returnArray[i][1];
}
}
objectStore = _factory.createObjectStore();
person = (Person) _factory.createComplexMetadataObject(objectStore, IdentityName, MetadataObjects.PERSON, personMetaID);
iSecurity.SetInternalPassword(IdentityName, IdentityPassword);
person.updateMetadataAll();
System.out.println("Password has been changed.");
return 0; // success
}
catch (MdException e)
{
Throwable t = e.getCause();
if (t != null)
{
String ErrorType = e.getSASMessageSeverity();
String ErrorMsg = e.getSASMessage();
if (ErrorType == null)
{
// If there is no SAS server message, write a Java/CORBA message.
}
else
{
// If there is a message from the server:
System.out.println(ErrorType + ": " + ErrorMsg);
}
if (t instanceof org.omg.CORBA.COMM_FAILURE)
{
// If there is an invalid port number or host name:
System.out.println(e.getLocalizedMessage());
}
else if (t instanceof org.omg.CORBA.NO_PERMISSION)
{
// If there is an invalid user ID or password:
System.out.println(e.getLocalizedMessage());
}
}
else
{
// If we cannot find a nested exception, get message and print.
System.out.println(e.getLocalizedMessage());
}
// If there is an error, print the entire stack trace.
e.printStackTrace();
}
catch (RemoteException e)
{
// Unknown exception.
e.printStackTrace();
}
catch (Exception e)
{
// Unknown exception.
e.printStackTrace();
}
System.out.println("Failure: Password has NOT been changed.");
return 1; // failure
}
}
2. 解决方案取决于
课堂上注意进口。要启用执行以下必要设置的代码CLASSPATH
环境变量。
在 Linux 上,您可以添加下一个命令%SASConfig%/Lev1/level_env_usermods.sh
:
export CLASSPATH=$CLASSPATH:%pathToJar%
在 Windows 上,您可以通过以下方式添加/更改环境变量Advanced system settings
那么应该在哪里搜索 jar 文件呢?它们位于文件夹中:
%SASHome%/SASVersionedJarRepository/eclipse/plugins/
我应该在路径中包含哪些文件?
我已经包含了 OMI 中使用的所有内容(开放元数据接口 https://support.sas.com/documentation/cdl/en/omaref/68021/HTML/default/viewer.htm#p0522mtdjome30n1j0t0ku3ziwoy.htm)。我还添加了log4j.jar
(没有这个罐子就无法工作。你的提示会很有帮助):
sas.oma.joma.jar
sas.oma.joma.rmt.jar
sas.oma.omi.jar
sas.svc.connection.jar
sas.core.jar
sas.entities.jar
sas.security.sspi.jar
log4j.jar
-
setPasswd.jar
(下一步就是你的罐子!)
从最近的版本中选择文件。例子:
我在这里设置文件v940m3f
(修复版本)。
其他方式是here https://support.sas.com/documentation/cdl/en/lrcon/69852/HTML/default/viewer.htm#n0swy2q7eouj2fn11g1o28q57v4u.htm.
3.编译setPasswd.jar
我尝试使用内部javac.exe
进入SAS,但它不能正常工作。所以你需要下载JDK来编译jar。我已经创建了 Bat 文件:
"C:\Program Files\Java\jdk1.8.0_121\bin\javac.exe" -source 1.7 -target 1.7 setPasswd.java
"C:\Program Files\Java\jdk1.8.0_121\bin\jar" -cf setPasswd.jar setPasswd.class
参数-source
and -target
如果您的 JDK 版本较高(在 SAS 中使用),将会很有帮助。您可以通过以下方式查看“sas”-java 的版本:
PROC javainfo all;
run;
在日志中搜索下一个字符串:
java.vm.规格.版本 = 1.7
4.最后。 SAS 基本调用
现在我们可以通过这个方法调用Java代码(所有方法都可用here https://support.sas.com/documentation/cdl/en/lrcon/69852/HTML/default/viewer.htm#n0swy2q7eouj2fn11g1o28q57v4u.htm):
data test;
dcl javaobj j ("setPasswd");
j.callIntMethod("connectToMetadata", "%SERVER%", "%PORT%", "%ADMIN%", "%{SAS002}HASHPASSORPASS%", rc1);
j.callIntMethod("changePasswd", "testPassLogin", "pass1", rc2);
j.delete();
run;
In log:
UserClass=Normal
AuthenticatedUserid=Unknown
IdentityName=testPass
IdentityType=Person
IdentityObjectID=A56RQPC2.AP00000I
Password has been changed.
现在是时候进行测试了。创建没有密码的新用户。
执行代码:
data test;
dcl javaobj j ("setPasswd");
j.callIntMethod("connectToMetadata", "&server.", "&port.", "&adm", "&pass", rc1);
j.callIntMethod("changePasswd", "TestUserForStack", "Overflow", rc2);
j.delete();
run;
现在我们的用户有了InternalLogin 对象。
Thanx.