所有由admin发布的文章

How to use SOAP API call SF

(1)Download WSDL files

Set up → API → API WSDL page → Generate Enterprise WSDL

This will take several minutes to create a page. right-click the page and save as wsdl.jsp.xml file on your local laptop.

(2)Download SOAP UI OpenSource from https://www.soapui.org/downloads/soapui/

(3)Install the SoapUI component using the package downloaded in the last step. Launch SoapUI, find file menu, select New SOAP Project. enter a project name.

(4) Update Login request, click Request1.



<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:enterprise.soap.sforce.com"> <soapenv:Header> </soapenv:Header> <soapenv:Body> <urn:login> <urn:username>your_username</urn:username> <urn:password>your_password+security_token</urn:password> </urn:login> </soapenv:Body> </soapenv:Envelope>

Click the green triangle on the top (play button) to run the request.

From the response, you can get the session id and the custom URL. it will be needed in the other calls.


(5)Create an account 

Update the custom URL and session ID. Specify the object name and account name.


Click the play button and then you can find this account in the SF.

Rails 上传CSV数据

def upload(file_name)
  csv = IO.read(file_name).split("\n")

  csv[1..-1].map do |x|
    data = x.split(',')
    sid = data[0].gsub(/"/, '')
    puts sid
    current_term = data[1].gsub(/"/, '').chop
    number_of_payments = data[2].gsub(/"/, '').chop

    Account.find_by(id: sid)&.update_columns current_term: current_term, number_of_payments: number_of_payments
  rescue StandardError => e
    puts data
    puts e.message
    next
  end
end

upload('DOC-2021.csv')


psql 数据表导入导出

$ createdb old_cms
$ psql old_cms

$ pg_restore –verbose –clean –no-acl –no-owner -h localhost -U aaa -d old_cms ~/Downloads/old_cms.dump

# select * from pg_tables;
# select * from “BlogPost”;
# select count(*) from “BlogPost”;
# \d “BlogPost”;
# select * from “BlogPost” where ‘FeaturedImageCaption’ != ”;

get the password by:
#sudo docker inspect cms | grep \”SS_DATABASE

#pg_dump -h preproduction-aaa.amazonaws.com -U ss -Fc ss > PG_DUMP_21_JULY_2021.dump -T *_versions

#scp ubuntu@preproduction-aaat.com:/home/ubuntu/PG_DUMP_21_JULY_2021.dump ~/Downloads/

scp ubuntu@preproduction-aaa.com:/home/ubuntu/PG_DUMP_21_JULY_2021.dump ~/Downloads/


导出整个表结构
pg_dump –host localhost -U aaa –file BlogCategory.dump –table “public.\”BlogCategory\”” “old_cms”

导入
psql -U aaa -d preprod-cms < BlogCategory.dump


导出表中数据数据 (不带header的方法)
COPY (select * from “BlogCategory”) TO ‘/Users/aaa/Downloads/BlogCategory.csv’ WITH csv;
导入 (不带header的csv数据)
COPY “BlogCategory” FROM ‘/Users/aaa/Downloads/BlogCategory.csv’ WITH csv;


# DELETE FROM “BlogCategory” where “ID” > 1;

$ scp ~/Downloads/BlogCategory.csv ubuntu@preproduction-aaa.com:/home/ubuntu/

$ psql -h preproduction-aaa.amazonaws.com -U ss -Fc ss

真正导入的时候发现前面要加一个反斜线 \

# \copy “BlogCategory” FROM ‘/home/ubuntu/BlogCategory.csv’ with csv;
由于csv文件改变了日期的格式,需要先run一下这行命令
# SET datestyle = dmy;

导出带header的csv文件

COPY (select * from “Blog_Live”) TO ‘/Users/aaa/Downloads/Blog_Live.csv’ WITH csv header;

拷贝到远程服务器
scp ~/Downloads/Blog_Live.csv ubuntu@preproduction-aaa.com:/home/ubuntu/

链接到远程服务器:

ssh ubuntu@preproduction-aaa.com
sudo docker inspect cms | grep \”SS_DATABASE

登录到服务器的数据库

psql -h preproduction-aaa.amazonaws.com -U ss -Fc ss

导入带header的csv文件

\copy “Blog_Live” FROM ‘/home/ubuntu/Blog_Live.csv’ with csv header;

keycloak 获取 access token validate token

import requests as req
import json

reqJson = {
    "client_id":"jwt-service",
    "client_secret": "qaaaaa-468a-4ba6-b71a-21672d1376be",
    "username": "aaa@aaa.com",
    "password": "123123",
    "grant_type": "password"
}

tokenUrl = 'http://localhost:8080/auth/realms/dev/protocol/openid-connect/token'

header = {
    "Content-Type": "application/x-www-form-urlencoded",
} 

response = req.post(tokenUrl, data=reqJson, headers=header)
if response.status_code > 200:
    print (response.text)
else:
    accessToken = json.loads(response.text)['access_token']
    print(accessToken)

validate the token

 header = {
    "Authorization": "Bearer " + access_token
} 
userinfoUrl = 'https://localhost:8080/auth/realms/customer/protocol/openid-connect/userinfo'

response = req.get(userinfoUrl, headers=header)    
print(response.text)

Salesforce Rest API 查找数据

官方文档:

https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/using_resources_working_with_records.htm

如何生成access token? 其中client id 和 client secret可以在connected app里找到,username和password为Salesforce里一个user的用户名和 密码 + security token


import requests as req
import json
 
testTokenUrl = "https://test.salesforce.com/services/oauth2/token"
testReqJson = {
    "client_id": "xxx",
    "client_secret": "xxx",
    "username": "sandbox_dev",
    "password": "password+securityToken",
    "grant_type": "password"
}
 
header = {
    "Content-Type": "application/x-www-form-urlencoded",
}
 
response = req.post(testTokenUrl, data=testReqJson, headers=header)
if response.status_code > 200:
    print (response.text)
else:
    token = json.loads(response.text)
    accessToken = json.loads(response.text)['access_token']

比较通用的方法是通过sql语句查询所需的数据

def get_record_type_id(token):
    header = {
        "Authorization": "Bearer " + token['access_token']
    }
    queryURL = token['instance_url'] + "/services/data/v47.0/query/?q="
    queryParams = "Select+Id+FROM+RecordType+WHERE+Name='Root Branch'"
    response = req.get(queryURL+queryParams, headers=header)
    
    if response.status_code == 200:
        return json.loads(response.text)['records'][0]['Id']
    else:
        raise ImportException('Error: '+response.text)

Salesforce Rest API 更新数据

官方文档:

https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_update_fields.htm

如何生成access token?其中client id 和 client secret可以在connected app里找到,username和password为Salesforce里一个user的用户名和密码,

import requests as req
import json

testTokenUrl = "https://test.salesforce.com/services/oauth2/token"
testReqJson = {
    "client_id": "xxx",
    "client_secret": "xxx",
    "username": "sandbox_dev",
    "password": "password+securityToken",
    "grant_type": "password"
}

header = {
    "Content-Type": "application/x-www-form-urlencoded",
}

response = req.post(testTokenUrl, data=testReqJson, headers=header)
if response.status_code > 200:
    print (response.text)
else:
    token = json.loads(response.text)
    accessToken = json.loads(response.text)['access_token']
    print(accessToken)

更新记录 Update a Record

curl https://yourInstance.salesforce.com/services/data/v20.0/sobjects/Account/001D000000INjVe -H “Authorization: Bearer token” -H “Content-Type: application/json” -d @patchaccount.json -X PATCH

如果SF返回的http code为204,说明更新成功

def update_record_type_id(token, RecordTypeId, loanOfficeNameId):
    print('Set record type id...')
    header = {
        "Content-Type": "application/json",
        "Authorization": "Bearer " + token['access_token']
    }
    params = {
        "RecordTypeId": RecordTypeId
    }
    body=json.JSONEncoder().encode(params)
    patchURL = token['instance_url'] + "/services/data/v47.0/sobjects/loan__Office_Name__c/"+loanOfficeNameId
    response = req.patch(patchURL,data=body, headers=header)
    if response.status_code == 204:
        print('set_record_type_id Done.')
    else:
        raise ImportException('Error: '+response.text)

更新user相关的数据

def set_user_branch(branchName='aaa'):
    token = get_token()
    header = {
        "Content-Type": "application/json",
        "Authorization": "Bearer " + token['access_token']
    }
    params = {
        "loan__Current_Branch__c": branchName,
        "loan__Default_Branch__c": branchName
    }
    index = token['id'].rfind('/')
    body=json.JSONEncoder().encode(params)
    patchURL = token['instance_url'] + "/services/data/v{}/sobjects/User/{}".format(SF_API_VERSION, token['id'][index+1:])
    #如果知道user id,可以简化为
    # patchURL = token['instance_url'] + "/services/data/v47.0/sobjects/User/"+Id
    response = req.patch(patchURL,data=body, headers=header)
    if response.status_code == 204:
        print('Done.')
    else:
        raise ImportException('Error: '+response.text)

BeautifulSoup解析本地文件

import requests
from bs4 import BeautifulSoup

apex_class = ''
apex_trigger = ''
custome_object = ''
profile = ''
others = ''
path = '/Users/aaa/Downloads/aaa.htm'
htmlfile = open(path, 'r')

htmlhandle = htmlfile.read()
soup = BeautifulSoup(htmlhandle, "lxml") 
#soup = BeautifulSoup(htmlhandle, "html.parser")

titles = soup.find_all("a", class_="link-gray-dark")
for title in titles:
    if 'src' in title.text:
        if '.cls' in title.text:
            apex_class += '\n'+title.text
        elif '.trigger' in title.text:
            apex_trigger += '\n'+title.text
        elif '.object' in title.text:
            custome_object += '\n'+title.text
        elif '.profile' in title.text:
            profile += '\n'+title.text
        else:
            others += '\n'+title.text
            
print ('apex_class:\n'+apex_class);
print ('apex_trigger:\n'+apex_trigger);
print ('custome_object:\n'+custome_object);
print ('profile:\n'+profile);
print ('others:\n'+others);

what is next

Retire deprecated micro app projects. (Repo, Codeship, S3)
Improve our code structure, how do we layout/split our components and services?https://indepth.dev/lean-angular-components/
Improve our mock API server.Smart or DumbState or StatelessScenario based
Improve the unit test experience, for developers. (Spectator vs TestBed)
E2E integration testing with Cypress (Relies on an improved mock API server)
Introduce Visual testing (Percy.io, BackstopJS — relies on mock API server and E2E tests)
Improving deployment process/scriptMulti application deploymentsSmarter releases (Auto tagging)
Storybooks for all common/shared UI Components
Introduce a shared Service Worker to handle all API communications

Google Social Login with Keycloak

0. Expose your local web server to the internet

https://dashboard.ngrok.com/get-started

My Keycloak is running in my local laptop localhost:8080. After publishing it to the internet. we could use http://325xxxx.ngrok.io to connect by anyone else.

1. Create a google application

(1) Create a google application at https://console.developers.google.com/ ,

(2) Create a new OAuth consent screen

(3) Create a client ID

save the id and secret, we will use it in Keycloak settings.

2.Setup Keycloak

(1) Create a new realm and client

While in the client, click the Installation tab. Under format option select “Keycloak OIDC JSON“.

Copy and paste this value in a file keycloak.json, we will use it later.

(2) Create an Identity Provider

Fill in the client Id and secret which we generated in the previous step

3. Create a web project

Create a web project which could use Keycloak for login. Use keycloak.json file for settings.

Use the public URL which generated in step 0 intead of localhost:8080

https://github.com/shiralwz/Keycloak-Angular-Auth

run yarn to install the lib, then run yarn start to start the server

4. Setup google redirect URIs

(1) Setup the redirect URI and authorized domains

5. Run web server and test

Click login link and redirected to Keycloak login page